{
 "cells": [
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-02-25T12:50:56.747859Z",
     "start_time": "2025-02-25T12:50:49.038524Z"
    }
   },
   "source": [
    "import matplotlib as mpl\n",
    "import matplotlib.pyplot as plt\n",
    "%matplotlib inline\n",
    "import numpy as np\n",
    "import sklearn\n",
    "import pandas as pd\n",
    "import os\n",
    "import sys\n",
    "import time\n",
    "from tqdm.auto import tqdm\n",
    "import torch\n",
    "import torch.nn as nn\n",
    "import torch.nn.functional as F\n",
    "\n",
    "print(sys.version_info)\n",
    "for module in mpl, np, pd, sklearn, torch:\n",
    "    print(module.__name__, module.__version__)\n",
    "    \n",
    "device = torch.device(\"cuda:0\") if torch.cuda.is_available() else torch.device(\"cpu\")\n",
    "print(device)\n"
   ],
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "sys.version_info(major=3, minor=12, micro=3, releaselevel='final', serial=0)\n",
      "matplotlib 3.10.0\n",
      "numpy 2.0.2\n",
      "pandas 2.2.3\n",
      "sklearn 1.6.1\n",
      "torch 2.6.0+cu126\n",
      "cuda:0\n"
     ]
    }
   ],
   "execution_count": 1
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 准备数据"
   ]
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-02-25T12:53:09.822938Z",
     "start_time": "2025-02-25T12:53:09.532031Z"
    }
   },
   "source": [
    "from sklearn.datasets import fetch_california_housing\n",
    "\n",
    "housing = fetch_california_housing(data_home='data')\n",
    "print(housing.DESCR)\n",
    "print(housing.data.shape)\n",
    "print(housing.target.shape)"
   ],
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      ".. _california_housing_dataset:\n",
      "\n",
      "California Housing dataset\n",
      "--------------------------\n",
      "\n",
      "**Data Set Characteristics:**\n",
      "\n",
      ":Number of Instances: 20640\n",
      "\n",
      ":Number of Attributes: 8 numeric, predictive attributes and the target\n",
      "\n",
      ":Attribute Information:\n",
      "    - MedInc        median income in block group\n",
      "    - HouseAge      median house age in block group\n",
      "    - AveRooms      average number of rooms per household\n",
      "    - AveBedrms     average number of bedrooms per household\n",
      "    - Population    block group population\n",
      "    - AveOccup      average number of household members\n",
      "    - Latitude      block group latitude\n",
      "    - Longitude     block group longitude\n",
      "\n",
      ":Missing Attribute Values: None\n",
      "\n",
      "This dataset was obtained from the StatLib repository.\n",
      "https://www.dcc.fc.up.pt/~ltorgo/Regression/cal_housing.html\n",
      "\n",
      "The target variable is the median house value for California districts,\n",
      "expressed in hundreds of thousands of dollars ($100,000).\n",
      "\n",
      "This dataset was derived from the 1990 U.S. census, using one row per census\n",
      "block group. A block group is the smallest geographical unit for which the U.S.\n",
      "Census Bureau publishes sample data (a block group typically has a population\n",
      "of 600 to 3,000 people).\n",
      "\n",
      "A household is a group of people residing within a home. Since the average\n",
      "number of rooms and bedrooms in this dataset are provided per household, these\n",
      "columns may take surprisingly large values for block groups with few households\n",
      "and many empty houses, such as vacation resorts.\n",
      "\n",
      "It can be downloaded/loaded using the\n",
      ":func:`sklearn.datasets.fetch_california_housing` function.\n",
      "\n",
      ".. rubric:: References\n",
      "\n",
      "- Pace, R. Kelley and Ronald Barry, Sparse Spatial Autoregressions,\n",
      "  Statistics and Probability Letters, 33 (1997) 291-297\n",
      "\n",
      "(20640, 8)\n",
      "(20640,)\n"
     ]
    }
   ],
   "execution_count": 2
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-02-25T12:53:12.913303Z",
     "start_time": "2025-02-25T12:53:12.909302Z"
    }
   },
   "source": [
    "# print(housing.data[0:5])\n",
    "import pprint  #打印的格式比较 好看\n",
    "\n",
    "pprint.pprint(housing.data[0:2])\n",
    "print('-'*50)\n",
    "pprint.pprint(housing.target[0:2])"
   ],
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "array([[ 8.32520000e+00,  4.10000000e+01,  6.98412698e+00,\n",
      "         1.02380952e+00,  3.22000000e+02,  2.55555556e+00,\n",
      "         3.78800000e+01, -1.22230000e+02],\n",
      "       [ 8.30140000e+00,  2.10000000e+01,  6.23813708e+00,\n",
      "         9.71880492e-01,  2.40100000e+03,  2.10984183e+00,\n",
      "         3.78600000e+01, -1.22220000e+02]])\n",
      "--------------------------------------------------\n",
      "array([4.526, 3.585])\n"
     ]
    }
   ],
   "execution_count": 3
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-02-25T12:55:00.212484Z",
     "start_time": "2025-02-25T12:54:59.926972Z"
    }
   },
   "source": [
    "from sklearn.model_selection import train_test_split\n",
    "\n",
    "#拆分训练集和测试集，random_state是随机种子,同样的随机数种子，是为了得到同样的随机值\n",
    "x_train_all, x_test, y_train_all, y_test = train_test_split(\n",
    "    housing.data, housing.target, random_state = 7)\n",
    "x_train, x_valid, y_train, y_valid = train_test_split(\n",
    "    x_train_all, y_train_all, random_state = 11)\n",
    "# 训练集\n",
    "print(x_train.shape, y_train.shape)\n",
    "# 验证集\n",
    "print(x_valid.shape, y_valid.shape)\n",
    "# 测试集\n",
    "print(x_test.shape, y_test.shape)\n",
    "\n",
    "dataset_maps = {\n",
    "    \"train\": [x_train, y_train], #训练集\n",
    "    \"valid\": [x_valid, y_valid], #验证集\n",
    "    \"test\": [x_test, y_test], #测试集\n",
    "} #把3个数据集都放到字典中\n"
   ],
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "(11610, 8) (11610,)\n",
      "(3870, 8) (3870,)\n",
      "(5160, 8) (5160,)\n"
     ]
    }
   ],
   "execution_count": 4
  },
  {
   "cell_type": "code",
   "source": [
    "type(x_train)"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-02-25T12:55:50.363458Z",
     "start_time": "2025-02-25T12:55:50.358938Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "numpy.ndarray"
      ]
     },
     "execution_count": 5,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 5
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-02-25T12:55:51.349395Z",
     "start_time": "2025-02-25T12:55:51.332245Z"
    }
   },
   "source": [
    "from sklearn.preprocessing import StandardScaler\n",
    "\n",
    "scaler = StandardScaler() #标准化\n",
    "scaler.fit(x_train) #fit和fit_transform的区别，fit是计算均值和方差，fit_transform是先fit，然后transform"
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "StandardScaler()"
      ],
      "text/html": [
       "<style>#sk-container-id-1 {\n",
       "  /* Definition of color scheme common for light and dark mode */\n",
       "  --sklearn-color-text: #000;\n",
       "  --sklearn-color-text-muted: #666;\n",
       "  --sklearn-color-line: gray;\n",
       "  /* Definition of color scheme for unfitted estimators */\n",
       "  --sklearn-color-unfitted-level-0: #fff5e6;\n",
       "  --sklearn-color-unfitted-level-1: #f6e4d2;\n",
       "  --sklearn-color-unfitted-level-2: #ffe0b3;\n",
       "  --sklearn-color-unfitted-level-3: chocolate;\n",
       "  /* Definition of color scheme for fitted estimators */\n",
       "  --sklearn-color-fitted-level-0: #f0f8ff;\n",
       "  --sklearn-color-fitted-level-1: #d4ebff;\n",
       "  --sklearn-color-fitted-level-2: #b3dbfd;\n",
       "  --sklearn-color-fitted-level-3: cornflowerblue;\n",
       "\n",
       "  /* Specific color for light theme */\n",
       "  --sklearn-color-text-on-default-background: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, black)));\n",
       "  --sklearn-color-background: var(--sg-background-color, var(--theme-background, var(--jp-layout-color0, white)));\n",
       "  --sklearn-color-border-box: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, black)));\n",
       "  --sklearn-color-icon: #696969;\n",
       "\n",
       "  @media (prefers-color-scheme: dark) {\n",
       "    /* Redefinition of color scheme for dark theme */\n",
       "    --sklearn-color-text-on-default-background: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, white)));\n",
       "    --sklearn-color-background: var(--sg-background-color, var(--theme-background, var(--jp-layout-color0, #111)));\n",
       "    --sklearn-color-border-box: var(--sg-text-color, var(--theme-code-foreground, var(--jp-content-font-color1, white)));\n",
       "    --sklearn-color-icon: #878787;\n",
       "  }\n",
       "}\n",
       "\n",
       "#sk-container-id-1 {\n",
       "  color: var(--sklearn-color-text);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 pre {\n",
       "  padding: 0;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 input.sk-hidden--visually {\n",
       "  border: 0;\n",
       "  clip: rect(1px 1px 1px 1px);\n",
       "  clip: rect(1px, 1px, 1px, 1px);\n",
       "  height: 1px;\n",
       "  margin: -1px;\n",
       "  overflow: hidden;\n",
       "  padding: 0;\n",
       "  position: absolute;\n",
       "  width: 1px;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-dashed-wrapped {\n",
       "  border: 1px dashed var(--sklearn-color-line);\n",
       "  margin: 0 0.4em 0.5em 0.4em;\n",
       "  box-sizing: border-box;\n",
       "  padding-bottom: 0.4em;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-container {\n",
       "  /* jupyter's `normalize.less` sets `[hidden] { display: none; }`\n",
       "     but bootstrap.min.css set `[hidden] { display: none !important; }`\n",
       "     so we also need the `!important` here to be able to override the\n",
       "     default hidden behavior on the sphinx rendered scikit-learn.org.\n",
       "     See: https://github.com/scikit-learn/scikit-learn/issues/21755 */\n",
       "  display: inline-block !important;\n",
       "  position: relative;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-text-repr-fallback {\n",
       "  display: none;\n",
       "}\n",
       "\n",
       "div.sk-parallel-item,\n",
       "div.sk-serial,\n",
       "div.sk-item {\n",
       "  /* draw centered vertical line to link estimators */\n",
       "  background-image: linear-gradient(var(--sklearn-color-text-on-default-background), var(--sklearn-color-text-on-default-background));\n",
       "  background-size: 2px 100%;\n",
       "  background-repeat: no-repeat;\n",
       "  background-position: center center;\n",
       "}\n",
       "\n",
       "/* Parallel-specific style estimator block */\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel-item::after {\n",
       "  content: \"\";\n",
       "  width: 100%;\n",
       "  border-bottom: 2px solid var(--sklearn-color-text-on-default-background);\n",
       "  flex-grow: 1;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel {\n",
       "  display: flex;\n",
       "  align-items: stretch;\n",
       "  justify-content: center;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  position: relative;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel-item {\n",
       "  display: flex;\n",
       "  flex-direction: column;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel-item:first-child::after {\n",
       "  align-self: flex-end;\n",
       "  width: 50%;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel-item:last-child::after {\n",
       "  align-self: flex-start;\n",
       "  width: 50%;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-parallel-item:only-child::after {\n",
       "  width: 0;\n",
       "}\n",
       "\n",
       "/* Serial-specific style estimator block */\n",
       "\n",
       "#sk-container-id-1 div.sk-serial {\n",
       "  display: flex;\n",
       "  flex-direction: column;\n",
       "  align-items: center;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  padding-right: 1em;\n",
       "  padding-left: 1em;\n",
       "}\n",
       "\n",
       "\n",
       "/* Toggleable style: style used for estimator/Pipeline/ColumnTransformer box that is\n",
       "clickable and can be expanded/collapsed.\n",
       "- Pipeline and ColumnTransformer use this feature and define the default style\n",
       "- Estimators will overwrite some part of the style using the `sk-estimator` class\n",
       "*/\n",
       "\n",
       "/* Pipeline and ColumnTransformer style (default) */\n",
       "\n",
       "#sk-container-id-1 div.sk-toggleable {\n",
       "  /* Default theme specific background. It is overwritten whether we have a\n",
       "  specific estimator or a Pipeline/ColumnTransformer */\n",
       "  background-color: var(--sklearn-color-background);\n",
       "}\n",
       "\n",
       "/* Toggleable label */\n",
       "#sk-container-id-1 label.sk-toggleable__label {\n",
       "  cursor: pointer;\n",
       "  display: flex;\n",
       "  width: 100%;\n",
       "  margin-bottom: 0;\n",
       "  padding: 0.5em;\n",
       "  box-sizing: border-box;\n",
       "  text-align: center;\n",
       "  align-items: start;\n",
       "  justify-content: space-between;\n",
       "  gap: 0.5em;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 label.sk-toggleable__label .caption {\n",
       "  font-size: 0.6rem;\n",
       "  font-weight: lighter;\n",
       "  color: var(--sklearn-color-text-muted);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 label.sk-toggleable__label-arrow:before {\n",
       "  /* Arrow on the left of the label */\n",
       "  content: \"▸\";\n",
       "  float: left;\n",
       "  margin-right: 0.25em;\n",
       "  color: var(--sklearn-color-icon);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 label.sk-toggleable__label-arrow:hover:before {\n",
       "  color: var(--sklearn-color-text);\n",
       "}\n",
       "\n",
       "/* Toggleable content - dropdown */\n",
       "\n",
       "#sk-container-id-1 div.sk-toggleable__content {\n",
       "  max-height: 0;\n",
       "  max-width: 0;\n",
       "  overflow: hidden;\n",
       "  text-align: left;\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-toggleable__content.fitted {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-toggleable__content pre {\n",
       "  margin: 0.2em;\n",
       "  border-radius: 0.25em;\n",
       "  color: var(--sklearn-color-text);\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-toggleable__content.fitted pre {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 input.sk-toggleable__control:checked~div.sk-toggleable__content {\n",
       "  /* Expand drop-down */\n",
       "  max-height: 200px;\n",
       "  max-width: 100%;\n",
       "  overflow: auto;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 input.sk-toggleable__control:checked~label.sk-toggleable__label-arrow:before {\n",
       "  content: \"▾\";\n",
       "}\n",
       "\n",
       "/* Pipeline/ColumnTransformer-specific style */\n",
       "\n",
       "#sk-container-id-1 div.sk-label input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-label.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Estimator-specific style */\n",
       "\n",
       "/* Colorize estimator box */\n",
       "#sk-container-id-1 div.sk-estimator input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-estimator.fitted input.sk-toggleable__control:checked~label.sk-toggleable__label {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-label label.sk-toggleable__label,\n",
       "#sk-container-id-1 div.sk-label label {\n",
       "  /* The background is the default theme color */\n",
       "  color: var(--sklearn-color-text-on-default-background);\n",
       "}\n",
       "\n",
       "/* On hover, darken the color of the background */\n",
       "#sk-container-id-1 div.sk-label:hover label.sk-toggleable__label {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "/* Label box, darken color on hover, fitted */\n",
       "#sk-container-id-1 div.sk-label.fitted:hover label.sk-toggleable__label.fitted {\n",
       "  color: var(--sklearn-color-text);\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Estimator label */\n",
       "\n",
       "#sk-container-id-1 div.sk-label label {\n",
       "  font-family: monospace;\n",
       "  font-weight: bold;\n",
       "  display: inline-block;\n",
       "  line-height: 1.2em;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-label-container {\n",
       "  text-align: center;\n",
       "}\n",
       "\n",
       "/* Estimator-specific */\n",
       "#sk-container-id-1 div.sk-estimator {\n",
       "  font-family: monospace;\n",
       "  border: 1px dotted var(--sklearn-color-border-box);\n",
       "  border-radius: 0.25em;\n",
       "  box-sizing: border-box;\n",
       "  margin-bottom: 0.5em;\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-0);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-estimator.fitted {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-0);\n",
       "}\n",
       "\n",
       "/* on hover */\n",
       "#sk-container-id-1 div.sk-estimator:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-2);\n",
       "}\n",
       "\n",
       "#sk-container-id-1 div.sk-estimator.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-2);\n",
       "}\n",
       "\n",
       "/* Specification for estimator info (e.g. \"i\" and \"?\") */\n",
       "\n",
       "/* Common style for \"i\" and \"?\" */\n",
       "\n",
       ".sk-estimator-doc-link,\n",
       "a:link.sk-estimator-doc-link,\n",
       "a:visited.sk-estimator-doc-link {\n",
       "  float: right;\n",
       "  font-size: smaller;\n",
       "  line-height: 1em;\n",
       "  font-family: monospace;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  border-radius: 1em;\n",
       "  height: 1em;\n",
       "  width: 1em;\n",
       "  text-decoration: none !important;\n",
       "  margin-left: 0.5em;\n",
       "  text-align: center;\n",
       "  /* unfitted */\n",
       "  border: var(--sklearn-color-unfitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-unfitted-level-1);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link.fitted,\n",
       "a:link.sk-estimator-doc-link.fitted,\n",
       "a:visited.sk-estimator-doc-link.fitted {\n",
       "  /* fitted */\n",
       "  border: var(--sklearn-color-fitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-fitted-level-1);\n",
       "}\n",
       "\n",
       "/* On hover */\n",
       "div.sk-estimator:hover .sk-estimator-doc-link:hover,\n",
       ".sk-estimator-doc-link:hover,\n",
       "div.sk-label-container:hover .sk-estimator-doc-link:hover,\n",
       ".sk-estimator-doc-link:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "div.sk-estimator.fitted:hover .sk-estimator-doc-link.fitted:hover,\n",
       ".sk-estimator-doc-link.fitted:hover,\n",
       "div.sk-label-container:hover .sk-estimator-doc-link.fitted:hover,\n",
       ".sk-estimator-doc-link.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "/* Span, style for the box shown on hovering the info icon */\n",
       ".sk-estimator-doc-link span {\n",
       "  display: none;\n",
       "  z-index: 9999;\n",
       "  position: relative;\n",
       "  font-weight: normal;\n",
       "  right: .2ex;\n",
       "  padding: .5ex;\n",
       "  margin: .5ex;\n",
       "  width: min-content;\n",
       "  min-width: 20ex;\n",
       "  max-width: 50ex;\n",
       "  color: var(--sklearn-color-text);\n",
       "  box-shadow: 2pt 2pt 4pt #999;\n",
       "  /* unfitted */\n",
       "  background: var(--sklearn-color-unfitted-level-0);\n",
       "  border: .5pt solid var(--sklearn-color-unfitted-level-3);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link.fitted span {\n",
       "  /* fitted */\n",
       "  background: var(--sklearn-color-fitted-level-0);\n",
       "  border: var(--sklearn-color-fitted-level-3);\n",
       "}\n",
       "\n",
       ".sk-estimator-doc-link:hover span {\n",
       "  display: block;\n",
       "}\n",
       "\n",
       "/* \"?\"-specific style due to the `<a>` HTML tag */\n",
       "\n",
       "#sk-container-id-1 a.estimator_doc_link {\n",
       "  float: right;\n",
       "  font-size: 1rem;\n",
       "  line-height: 1em;\n",
       "  font-family: monospace;\n",
       "  background-color: var(--sklearn-color-background);\n",
       "  border-radius: 1rem;\n",
       "  height: 1rem;\n",
       "  width: 1rem;\n",
       "  text-decoration: none;\n",
       "  /* unfitted */\n",
       "  color: var(--sklearn-color-unfitted-level-1);\n",
       "  border: var(--sklearn-color-unfitted-level-1) 1pt solid;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 a.estimator_doc_link.fitted {\n",
       "  /* fitted */\n",
       "  border: var(--sklearn-color-fitted-level-1) 1pt solid;\n",
       "  color: var(--sklearn-color-fitted-level-1);\n",
       "}\n",
       "\n",
       "/* On hover */\n",
       "#sk-container-id-1 a.estimator_doc_link:hover {\n",
       "  /* unfitted */\n",
       "  background-color: var(--sklearn-color-unfitted-level-3);\n",
       "  color: var(--sklearn-color-background);\n",
       "  text-decoration: none;\n",
       "}\n",
       "\n",
       "#sk-container-id-1 a.estimator_doc_link.fitted:hover {\n",
       "  /* fitted */\n",
       "  background-color: var(--sklearn-color-fitted-level-3);\n",
       "}\n",
       "</style><div id=\"sk-container-id-1\" class=\"sk-top-container\"><div class=\"sk-text-repr-fallback\"><pre>StandardScaler()</pre><b>In a Jupyter environment, please rerun this cell to show the HTML representation or trust the notebook. <br />On GitHub, the HTML representation is unable to render, please try loading this page with nbviewer.org.</b></div><div class=\"sk-container\" hidden><div class=\"sk-item\"><div class=\"sk-estimator fitted sk-toggleable\"><input class=\"sk-toggleable__control sk-hidden--visually\" id=\"sk-estimator-id-1\" type=\"checkbox\" checked><label for=\"sk-estimator-id-1\" class=\"sk-toggleable__label fitted sk-toggleable__label-arrow\"><div><div>StandardScaler</div></div><div><a class=\"sk-estimator-doc-link fitted\" rel=\"noreferrer\" target=\"_blank\" href=\"https://scikit-learn.org/1.6/modules/generated/sklearn.preprocessing.StandardScaler.html\">?<span>Documentation for StandardScaler</span></a><span class=\"sk-estimator-doc-link fitted\">i<span>Fitted</span></span></div></label><div class=\"sk-toggleable__content fitted\"><pre>StandardScaler()</pre></div> </div></div></div></div>"
      ]
     },
     "execution_count": 6,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 6
  },
  {
   "cell_type": "code",
   "source": [
    "np.array(1).shape"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-02-25T12:56:05.435344Z",
     "start_time": "2025-02-25T12:56:05.432243Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "()"
      ]
     },
     "execution_count": 7,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 7
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### 构建数据集"
   ]
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-02-25T12:59:09.853908Z",
     "start_time": "2025-02-25T12:59:09.844638Z"
    }
   },
   "source": [
    "#构建私有数据集，就需要用如下方式\n",
    "from torch.utils.data import Dataset\n",
    "\n",
    "class HousingDataset(Dataset):\n",
    "    def __init__(self, mode='train'):\n",
    "        self.x, self.y = dataset_maps[mode] #x,y都是ndarray类型\n",
    "        self.x = torch.from_numpy(scaler.transform(self.x)).float() #from_numpy将NumPy数组转换成PyTorch张量\n",
    "        self.y = torch.from_numpy(self.y).float().reshape(-1, 1) #处理为多行1列的tensor类型,因为__getitem__切片时需要\n",
    "            \n",
    "    def __len__(self): #必须写\n",
    "        return len(self.x) #返回数据集的长度,0维的size\n",
    "    \n",
    "    def __getitem__(self, idx): #idx是索引，返回的是数据和标签，这里是一个样本\n",
    "        return self.x[idx], self.y[idx]\n",
    "    \n",
    "#train_ds是dataset类型的数据，与前面例子的FashionMNIST类型一致\n",
    "train_ds = HousingDataset(\"train\")\n",
    "valid_ds = HousingDataset(\"valid\")\n",
    "test_ds = HousingDataset(\"test\")"
   ],
   "outputs": [],
   "execution_count": 8
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-02-25T12:59:10.554734Z",
     "start_time": "2025-02-25T12:59:10.551186Z"
    }
   },
   "cell_type": "code",
   "source": "type(train_ds)",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "__main__.HousingDataset"
      ]
     },
     "execution_count": 9,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 9
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-02-25T13:52:07.345505Z",
     "start_time": "2025-02-25T13:52:07.337155Z"
    }
   },
   "source": "train_ds[1]",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "(tensor([-0.2981,  0.3523, -0.1092, -0.2506, -0.0341, -0.0060,  1.0806, -1.0611]),\n",
       " tensor([1.5140]))"
      ]
     },
     "execution_count": 10,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 10
  },
  {
   "cell_type": "code",
   "source": [
    "train_ds[0][0]"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-02-25T13:52:09.267669Z",
     "start_time": "2025-02-25T13:52:09.262290Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "tensor([ 0.8015,  0.2722, -0.1162, -0.2023, -0.5431, -0.0210, -0.5898, -0.0824])"
      ]
     },
     "execution_count": 11,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 11
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "### DataLoader"
   ]
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-02-25T13:52:15.152559Z",
     "start_time": "2025-02-25T13:52:15.148734Z"
    }
   },
   "source": [
    "from torch.utils.data import DataLoader\n",
    "\n",
    "#放到DataLoader中的train_ds, valid_ds, test_ds都是dataset类型的数据\n",
    "batch_size = 16 #batch_size是可以调的超参数\n",
    "train_loader = DataLoader(train_ds, batch_size=batch_size, shuffle=True)\n",
    "val_loader = DataLoader(valid_ds, batch_size=batch_size, shuffle=False)\n",
    "test_loader = DataLoader(test_ds, batch_size=batch_size, shuffle=False)"
   ],
   "outputs": [],
   "execution_count": 12
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 定义模型"
   ]
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-02-25T13:53:06.371833Z",
     "start_time": "2025-02-25T13:53:06.367828Z"
    }
   },
   "source": [
    "#回归模型我们只需要1个数\n",
    "\n",
    "class NeuralNetwork(nn.Module):\n",
    "    def __init__(self, input_dim=8):\n",
    "        super().__init__()\n",
    "        self.linear_relu_stack = nn.Sequential(\n",
    "            nn.Linear(input_dim, 30),\n",
    "            nn.ReLU(),\n",
    "            nn.Linear(30, 1)\n",
    "            )\n",
    "        \n",
    "    def forward(self, x):\n",
    "        # x.shape [batch size, 8]\n",
    "        logits = self.linear_relu_stack(x)\n",
    "        # logits.shape [batch size, 1]\n",
    "        return logits"
   ],
   "outputs": [],
   "execution_count": 13
  },
  {
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-02-25T13:53:21.565216Z",
     "start_time": "2025-02-25T13:53:21.561948Z"
    }
   },
   "cell_type": "code",
   "source": "8*30+30+30*1+1",
   "outputs": [
    {
     "data": {
      "text/plain": [
       "301"
      ]
     },
     "execution_count": 14,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 14
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-02-25T13:54:32.903412Z",
     "start_time": "2025-02-25T13:54:32.898404Z"
    }
   },
   "source": [
    "class EarlyStopCallback:\n",
    "    def __init__(self, patience=5, min_delta=0.01):\n",
    "        \"\"\"\n",
    "\n",
    "        Args:\n",
    "            patience (int, optional): Number of epochs with no improvement after which training will be stopped.. Defaults to 5.\n",
    "            min_delta (float, optional): Minimum change in the monitored quantity to qualify as an improvement, i.e. an absolute \n",
    "                change of less than min_delta, will count as no improvement. Defaults to 0.01.\n",
    "        \"\"\"\n",
    "        self.patience = patience\n",
    "        self.min_delta = min_delta\n",
    "        self.best_metric = -1\n",
    "        self.counter = 0\n",
    "        \n",
    "    def __call__(self, metric):\n",
    "        if metric >= self.best_metric + self.min_delta:\n",
    "            # update best metric\n",
    "            self.best_metric = metric\n",
    "            # reset counter \n",
    "            self.counter = 0\n",
    "        else: \n",
    "            self.counter += 1\n",
    "            \n",
    "    @property\n",
    "    def early_stop(self):\n",
    "        return self.counter >= self.patience\n"
   ],
   "outputs": [],
   "execution_count": 15
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-02-25T13:54:38.649103Z",
     "start_time": "2025-02-25T13:54:38.645983Z"
    }
   },
   "source": [
    "from sklearn.metrics import accuracy_score\n",
    "\n",
    "@torch.no_grad()\n",
    "def evaluating(model, dataloader, loss_fct):\n",
    "    loss_list = []\n",
    "    for datas, labels in dataloader:\n",
    "        datas = datas.to(device)\n",
    "        labels = labels.to(device)\n",
    "        # 前向计算\n",
    "        logits = model(datas)\n",
    "        loss = loss_fct(logits, labels)         # 验证集损失\n",
    "        loss_list.append(loss.item())\n",
    "        \n",
    "    return np.mean(loss_list)\n"
   ],
   "outputs": [],
   "execution_count": 16
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-02-25T13:55:55.733786Z",
     "start_time": "2025-02-25T13:54:56.276902Z"
    }
   },
   "source": [
    "# 训练\n",
    "def training(\n",
    "    model, \n",
    "    train_loader, \n",
    "    val_loader, \n",
    "    epoch, \n",
    "    loss_fct, \n",
    "    optimizer,\n",
    "    early_stop_callback=None,\n",
    "    eval_step=500,\n",
    "    ):\n",
    "    record_dict = {\n",
    "        \"train\": [],\n",
    "        \"val\": []\n",
    "    }\n",
    "    \n",
    "    global_step = 0\n",
    "    model.train()\n",
    "    with tqdm(total=epoch * len(train_loader)) as pbar:\n",
    "        for epoch_id in range(epoch):\n",
    "            # training\n",
    "            for datas, labels in train_loader:#11610/16=726\n",
    "                datas = datas.to(device)\n",
    "                labels = labels.to(device)\n",
    "                # 梯度清空\n",
    "                optimizer.zero_grad()\n",
    "                # 模型前向计算\n",
    "                logits = model(datas) #得到预测值\n",
    "                # 计算损失\n",
    "                loss = loss_fct(logits, labels)\n",
    "                # 梯度回传\n",
    "                loss.backward()\n",
    "                # 调整优化器，包括学习率的变动等\n",
    "                optimizer.step()\n",
    " \n",
    "                loss = loss.cpu().item() #转为cpu类型，item()是取值\n",
    "                # record\n",
    "                \n",
    "                record_dict[\"train\"].append({\n",
    "                    \"loss\": loss, \"step\": global_step\n",
    "                })\n",
    "                \n",
    "                # evaluating\n",
    "                if global_step % eval_step == 0:\n",
    "                    model.eval()\n",
    "                    val_loss = evaluating(model, val_loader, loss_fct)\n",
    "                    record_dict[\"val\"].append({\n",
    "                        \"loss\": val_loss, \"step\": global_step\n",
    "                    })\n",
    "                    model.train()\n",
    "\n",
    "                    # 早停 Early Stop\n",
    "                    if early_stop_callback is not None:\n",
    "                        early_stop_callback(-val_loss) #根据验证集的损失来实现早停\n",
    "                        if early_stop_callback.early_stop:\n",
    "                            print(f\"Early stop at epoch {epoch_id} / global_step {global_step}\")\n",
    "                            return record_dict\n",
    "                    \n",
    "                # udate step\n",
    "                global_step += 1\n",
    "                pbar.update(1)\n",
    "                pbar.set_postfix({\"epoch\": epoch_id})\n",
    "        \n",
    "    return record_dict\n",
    "        \n",
    "\n",
    "epoch = 100\n",
    "\n",
    "model = NeuralNetwork()\n",
    "\n",
    "# 1. 定义损失函数 采用MSE损失,均方误差\n",
    "loss_fct = nn.MSELoss()\n",
    "# 2. 定义优化器 采用SGD\n",
    "# Optimizers specified in the torch.optim package\n",
    "optimizer = torch.optim.SGD(model.parameters(), lr=0.001, momentum=0.9)\n",
    "\n",
    "# 3. early stop\n",
    "early_stop_callback = EarlyStopCallback(patience=10, min_delta=1e-3)\n",
    "\n",
    "model = model.to(device)\n",
    "record = training(\n",
    "    model, \n",
    "    train_loader, \n",
    "    val_loader, \n",
    "    epoch, \n",
    "    loss_fct, \n",
    "    optimizer, \n",
    "    early_stop_callback=early_stop_callback,\n",
    "    eval_step=len(train_loader)\n",
    "    )"
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "  0%|          | 0/72600 [00:00<?, ?it/s]"
      ],
      "application/vnd.jupyter.widget-view+json": {
       "version_major": 2,
       "version_minor": 0,
       "model_id": "7036712ae4d549569b9531d03db0f22d"
      }
     },
     "metadata": {},
     "output_type": "display_data"
    },
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n",
      "IOPub message rate exceeded.\n",
      "The Jupyter server will temporarily stop sending output\n",
      "to the client in order to avoid crashing it.\n",
      "To change this limit, set the config variable\n",
      "`--ServerApp.iopub_msg_rate_limit`.\n",
      "\n",
      "Current values:\n",
      "ServerApp.iopub_msg_rate_limit=1000.0 (msgs/sec)\n",
      "ServerApp.rate_limit_window=3.0 (secs)\n",
      "\n"
     ]
    },
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Early stop at epoch 40 / global_step 29040\n"
     ]
    }
   ],
   "execution_count": 17
  },
  {
   "cell_type": "code",
   "source": [
    "record"
   ],
   "metadata": {
    "collapsed": false,
    "ExecuteTime": {
     "end_time": "2025-02-25T14:18:46.682442Z",
     "start_time": "2025-02-25T14:18:46.655577Z"
    }
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "{'train': [{'loss': 3.4236788749694824, 'step': 0},\n",
       "  {'loss': 5.1009521484375, 'step': 1},\n",
       "  {'loss': 5.097630977630615, 'step': 2},\n",
       "  {'loss': 5.778499603271484, 'step': 3},\n",
       "  {'loss': 5.564082145690918, 'step': 4},\n",
       "  {'loss': 3.996345281600952, 'step': 5},\n",
       "  {'loss': 3.944488525390625, 'step': 6},\n",
       "  {'loss': 2.587735414505005, 'step': 7},\n",
       "  {'loss': 6.512445449829102, 'step': 8},\n",
       "  {'loss': 2.8493571281433105, 'step': 9},\n",
       "  {'loss': 5.788990020751953, 'step': 10},\n",
       "  {'loss': 2.8714704513549805, 'step': 11},\n",
       "  {'loss': 2.8869853019714355, 'step': 12},\n",
       "  {'loss': 3.1725900173187256, 'step': 13},\n",
       "  {'loss': 1.780888319015503, 'step': 14},\n",
       "  {'loss': 2.887998104095459, 'step': 15},\n",
       "  {'loss': 4.45572566986084, 'step': 16},\n",
       "  {'loss': 1.8056895732879639, 'step': 17},\n",
       "  {'loss': 2.03517484664917, 'step': 18},\n",
       "  {'loss': 1.547060251235962, 'step': 19},\n",
       "  {'loss': 0.6155006885528564, 'step': 20},\n",
       "  {'loss': 1.3783901929855347, 'step': 21},\n",
       "  {'loss': 1.2539280652999878, 'step': 22},\n",
       "  {'loss': 1.5499818325042725, 'step': 23},\n",
       "  {'loss': 0.7708901166915894, 'step': 24},\n",
       "  {'loss': 1.3241034746170044, 'step': 25},\n",
       "  {'loss': 1.4264857769012451, 'step': 26},\n",
       "  {'loss': 0.5908565521240234, 'step': 27},\n",
       "  {'loss': 1.9616079330444336, 'step': 28},\n",
       "  {'loss': 1.812200903892517, 'step': 29},\n",
       "  {'loss': 1.2213314771652222, 'step': 30},\n",
       "  {'loss': 1.6110423803329468, 'step': 31},\n",
       "  {'loss': 0.7523875832557678, 'step': 32},\n",
       "  {'loss': 1.379774570465088, 'step': 33},\n",
       "  {'loss': 1.1868557929992676, 'step': 34},\n",
       "  {'loss': 1.14567232131958, 'step': 35},\n",
       "  {'loss': 0.77430260181427, 'step': 36},\n",
       "  {'loss': 0.4286162853240967, 'step': 37},\n",
       "  {'loss': 0.8377162218093872, 'step': 38},\n",
       "  {'loss': 1.6388901472091675, 'step': 39},\n",
       "  {'loss': 1.1200878620147705, 'step': 40},\n",
       "  {'loss': 0.8503268957138062, 'step': 41},\n",
       "  {'loss': 0.8584855198860168, 'step': 42},\n",
       "  {'loss': 0.5791549682617188, 'step': 43},\n",
       "  {'loss': 0.6769548654556274, 'step': 44},\n",
       "  {'loss': 1.1616597175598145, 'step': 45},\n",
       "  {'loss': 1.2310535907745361, 'step': 46},\n",
       "  {'loss': 0.7238325476646423, 'step': 47},\n",
       "  {'loss': 1.1434423923492432, 'step': 48},\n",
       "  {'loss': 0.8996605277061462, 'step': 49},\n",
       "  {'loss': 0.9443995356559753, 'step': 50},\n",
       "  {'loss': 0.5328652262687683, 'step': 51},\n",
       "  {'loss': 1.3500497341156006, 'step': 52},\n",
       "  {'loss': 0.40594977140426636, 'step': 53},\n",
       "  {'loss': 0.2853059470653534, 'step': 54},\n",
       "  {'loss': 1.2187628746032715, 'step': 55},\n",
       "  {'loss': 0.698258638381958, 'step': 56},\n",
       "  {'loss': 0.8625897169113159, 'step': 57},\n",
       "  {'loss': 0.9298540353775024, 'step': 58},\n",
       "  {'loss': 1.3081130981445312, 'step': 59},\n",
       "  {'loss': 1.2543184757232666, 'step': 60},\n",
       "  {'loss': 0.49738359451293945, 'step': 61},\n",
       "  {'loss': 0.715477705001831, 'step': 62},\n",
       "  {'loss': 1.0866867303848267, 'step': 63},\n",
       "  {'loss': 0.7248895168304443, 'step': 64},\n",
       "  {'loss': 0.9647786617279053, 'step': 65},\n",
       "  {'loss': 0.32939526438713074, 'step': 66},\n",
       "  {'loss': 1.710798978805542, 'step': 67},\n",
       "  {'loss': 0.8674706816673279, 'step': 68},\n",
       "  {'loss': 0.8843669891357422, 'step': 69},\n",
       "  {'loss': 0.6674103736877441, 'step': 70},\n",
       "  {'loss': 0.535969078540802, 'step': 71},\n",
       "  {'loss': 1.1374043226242065, 'step': 72},\n",
       "  {'loss': 0.8053151369094849, 'step': 73},\n",
       "  {'loss': 0.1809370517730713, 'step': 74},\n",
       "  {'loss': 0.5264890789985657, 'step': 75},\n",
       "  {'loss': 0.33404475450515747, 'step': 76},\n",
       "  {'loss': 0.7173222303390503, 'step': 77},\n",
       "  {'loss': 0.8958060145378113, 'step': 78},\n",
       "  {'loss': 1.4361073970794678, 'step': 79},\n",
       "  {'loss': 1.248213529586792, 'step': 80},\n",
       "  {'loss': 0.3338056206703186, 'step': 81},\n",
       "  {'loss': 0.7118383646011353, 'step': 82},\n",
       "  {'loss': 0.47604241967201233, 'step': 83},\n",
       "  {'loss': 0.5129005908966064, 'step': 84},\n",
       "  {'loss': 0.9541107416152954, 'step': 85},\n",
       "  {'loss': 0.7105257511138916, 'step': 86},\n",
       "  {'loss': 0.5359382629394531, 'step': 87},\n",
       "  {'loss': 0.2755870223045349, 'step': 88},\n",
       "  {'loss': 0.17226533591747284, 'step': 89},\n",
       "  {'loss': 1.7662653923034668, 'step': 90},\n",
       "  {'loss': 0.42334848642349243, 'step': 91},\n",
       "  {'loss': 1.0222055912017822, 'step': 92},\n",
       "  {'loss': 0.6739349365234375, 'step': 93},\n",
       "  {'loss': 1.3487324714660645, 'step': 94},\n",
       "  {'loss': 0.8708919286727905, 'step': 95},\n",
       "  {'loss': 1.0912871360778809, 'step': 96},\n",
       "  {'loss': 0.5561671853065491, 'step': 97},\n",
       "  {'loss': 0.7986489534378052, 'step': 98},\n",
       "  {'loss': 0.7636951208114624, 'step': 99},\n",
       "  {'loss': 1.0667718648910522, 'step': 100},\n",
       "  {'loss': 0.47726473212242126, 'step': 101},\n",
       "  {'loss': 0.662295937538147, 'step': 102},\n",
       "  {'loss': 1.0334550142288208, 'step': 103},\n",
       "  {'loss': 0.5971571207046509, 'step': 104},\n",
       "  {'loss': 0.4165937900543213, 'step': 105},\n",
       "  {'loss': 0.4205448031425476, 'step': 106},\n",
       "  {'loss': 0.5714501142501831, 'step': 107},\n",
       "  {'loss': 0.2577182948589325, 'step': 108},\n",
       "  {'loss': 0.3779434561729431, 'step': 109},\n",
       "  {'loss': 0.3507564961910248, 'step': 110},\n",
       "  {'loss': 0.763599157333374, 'step': 111},\n",
       "  {'loss': 0.36733052134513855, 'step': 112},\n",
       "  {'loss': 0.4942465126514435, 'step': 113},\n",
       "  {'loss': 0.4873439073562622, 'step': 114},\n",
       "  {'loss': 0.8635623455047607, 'step': 115},\n",
       "  {'loss': 0.9559151530265808, 'step': 116},\n",
       "  {'loss': 0.22170858085155487, 'step': 117},\n",
       "  {'loss': 0.7440662980079651, 'step': 118},\n",
       "  {'loss': 1.0023109912872314, 'step': 119},\n",
       "  {'loss': 0.48596876859664917, 'step': 120},\n",
       "  {'loss': 2.604973077774048, 'step': 121},\n",
       "  {'loss': 0.4140685200691223, 'step': 122},\n",
       "  {'loss': 0.33951717615127563, 'step': 123},\n",
       "  {'loss': 0.20261149108409882, 'step': 124},\n",
       "  {'loss': 0.34878575801849365, 'step': 125},\n",
       "  {'loss': 0.34524771571159363, 'step': 126},\n",
       "  {'loss': 0.5860580801963806, 'step': 127},\n",
       "  {'loss': 0.30088311433792114, 'step': 128},\n",
       "  {'loss': 1.0024150609970093, 'step': 129},\n",
       "  {'loss': 1.1904959678649902, 'step': 130},\n",
       "  {'loss': 0.969448447227478, 'step': 131},\n",
       "  {'loss': 0.20590823888778687, 'step': 132},\n",
       "  {'loss': 0.8850849270820618, 'step': 133},\n",
       "  {'loss': 1.3486871719360352, 'step': 134},\n",
       "  {'loss': 0.6983350515365601, 'step': 135},\n",
       "  {'loss': 0.7984341382980347, 'step': 136},\n",
       "  {'loss': 0.8405128121376038, 'step': 137},\n",
       "  {'loss': 1.4347718954086304, 'step': 138},\n",
       "  {'loss': 0.4982561469078064, 'step': 139},\n",
       "  {'loss': 0.7414264678955078, 'step': 140},\n",
       "  {'loss': 0.5474792718887329, 'step': 141},\n",
       "  {'loss': 0.48912179470062256, 'step': 142},\n",
       "  {'loss': 0.49321556091308594, 'step': 143},\n",
       "  {'loss': 0.3778951168060303, 'step': 144},\n",
       "  {'loss': 0.17954307794570923, 'step': 145},\n",
       "  {'loss': 0.6352583765983582, 'step': 146},\n",
       "  {'loss': 0.17210355401039124, 'step': 147},\n",
       "  {'loss': 0.7472593784332275, 'step': 148},\n",
       "  {'loss': 0.6767047643661499, 'step': 149},\n",
       "  {'loss': 0.9746163487434387, 'step': 150},\n",
       "  {'loss': 0.6215137839317322, 'step': 151},\n",
       "  {'loss': 0.5230855345726013, 'step': 152},\n",
       "  {'loss': 0.6021358966827393, 'step': 153},\n",
       "  {'loss': 0.6150804162025452, 'step': 154},\n",
       "  {'loss': 1.1196885108947754, 'step': 155},\n",
       "  {'loss': 0.42112934589385986, 'step': 156},\n",
       "  {'loss': 0.5507240891456604, 'step': 157},\n",
       "  {'loss': 1.450216293334961, 'step': 158},\n",
       "  {'loss': 0.37615108489990234, 'step': 159},\n",
       "  {'loss': 0.731296956539154, 'step': 160},\n",
       "  {'loss': 0.46304595470428467, 'step': 161},\n",
       "  {'loss': 0.40292561054229736, 'step': 162},\n",
       "  {'loss': 0.47708407044410706, 'step': 163},\n",
       "  {'loss': 0.527716875076294, 'step': 164},\n",
       "  {'loss': 0.5437581539154053, 'step': 165},\n",
       "  {'loss': 0.3166666030883789, 'step': 166},\n",
       "  {'loss': 0.7753974199295044, 'step': 167},\n",
       "  {'loss': 0.11599947512149811, 'step': 168},\n",
       "  {'loss': 0.5796792507171631, 'step': 169},\n",
       "  {'loss': 0.8931158185005188, 'step': 170},\n",
       "  {'loss': 0.9640474915504456, 'step': 171},\n",
       "  {'loss': 0.4650082588195801, 'step': 172},\n",
       "  {'loss': 0.3878467082977295, 'step': 173},\n",
       "  {'loss': 0.586980402469635, 'step': 174},\n",
       "  {'loss': 0.3396291732788086, 'step': 175},\n",
       "  {'loss': 0.34845978021621704, 'step': 176},\n",
       "  {'loss': 1.326876163482666, 'step': 177},\n",
       "  {'loss': 0.9843176007270813, 'step': 178},\n",
       "  {'loss': 0.5795053243637085, 'step': 179},\n",
       "  {'loss': 0.37282806634902954, 'step': 180},\n",
       "  {'loss': 1.038522481918335, 'step': 181},\n",
       "  {'loss': 0.5829010605812073, 'step': 182},\n",
       "  {'loss': 0.695679783821106, 'step': 183},\n",
       "  {'loss': 0.547646164894104, 'step': 184},\n",
       "  {'loss': 0.5422769784927368, 'step': 185},\n",
       "  {'loss': 0.2615611255168915, 'step': 186},\n",
       "  {'loss': 0.19001346826553345, 'step': 187},\n",
       "  {'loss': 0.5417725443840027, 'step': 188},\n",
       "  {'loss': 0.42600297927856445, 'step': 189},\n",
       "  {'loss': 0.44337618350982666, 'step': 190},\n",
       "  {'loss': 0.6659520864486694, 'step': 191},\n",
       "  {'loss': 0.16131950914859772, 'step': 192},\n",
       "  {'loss': 0.48154574632644653, 'step': 193},\n",
       "  {'loss': 0.10786552727222443, 'step': 194},\n",
       "  {'loss': 0.7581161260604858, 'step': 195},\n",
       "  {'loss': 0.6583530902862549, 'step': 196},\n",
       "  {'loss': 0.40656131505966187, 'step': 197},\n",
       "  {'loss': 0.3173999786376953, 'step': 198},\n",
       "  {'loss': 1.3020155429840088, 'step': 199},\n",
       "  {'loss': 0.5654032826423645, 'step': 200},\n",
       "  {'loss': 0.28435176610946655, 'step': 201},\n",
       "  {'loss': 0.3147920072078705, 'step': 202},\n",
       "  {'loss': 0.3034149408340454, 'step': 203},\n",
       "  {'loss': 0.40730324387550354, 'step': 204},\n",
       "  {'loss': 0.8556671142578125, 'step': 205},\n",
       "  {'loss': 0.32463064789772034, 'step': 206},\n",
       "  {'loss': 0.47439059615135193, 'step': 207},\n",
       "  {'loss': 1.2312133312225342, 'step': 208},\n",
       "  {'loss': 0.8084081411361694, 'step': 209},\n",
       "  {'loss': 0.15873229503631592, 'step': 210},\n",
       "  {'loss': 0.7436487078666687, 'step': 211},\n",
       "  {'loss': 0.40991276502609253, 'step': 212},\n",
       "  {'loss': 0.5056031942367554, 'step': 213},\n",
       "  {'loss': 0.23875528573989868, 'step': 214},\n",
       "  {'loss': 0.21775966882705688, 'step': 215},\n",
       "  {'loss': 0.37109220027923584, 'step': 216},\n",
       "  {'loss': 0.3591397702693939, 'step': 217},\n",
       "  {'loss': 0.6310341358184814, 'step': 218},\n",
       "  {'loss': 0.45567458868026733, 'step': 219},\n",
       "  {'loss': 0.6437959671020508, 'step': 220},\n",
       "  {'loss': 0.8847194314002991, 'step': 221},\n",
       "  {'loss': 1.0857875347137451, 'step': 222},\n",
       "  {'loss': 0.4186246395111084, 'step': 223},\n",
       "  {'loss': 0.726331889629364, 'step': 224},\n",
       "  {'loss': 0.6907711625099182, 'step': 225},\n",
       "  {'loss': 0.6885014772415161, 'step': 226},\n",
       "  {'loss': 0.1737033575773239, 'step': 227},\n",
       "  {'loss': 0.8317902088165283, 'step': 228},\n",
       "  {'loss': 0.4224035143852234, 'step': 229},\n",
       "  {'loss': 0.4100126028060913, 'step': 230},\n",
       "  {'loss': 0.6019315719604492, 'step': 231},\n",
       "  {'loss': 0.457756906747818, 'step': 232},\n",
       "  {'loss': 0.26419591903686523, 'step': 233},\n",
       "  {'loss': 0.4068508446216583, 'step': 234},\n",
       "  {'loss': 0.48031777143478394, 'step': 235},\n",
       "  {'loss': 0.6567098498344421, 'step': 236},\n",
       "  {'loss': 0.44082123041152954, 'step': 237},\n",
       "  {'loss': 0.4383907616138458, 'step': 238},\n",
       "  {'loss': 0.5209239721298218, 'step': 239},\n",
       "  {'loss': 0.555545449256897, 'step': 240},\n",
       "  {'loss': 0.5557934641838074, 'step': 241},\n",
       "  {'loss': 0.36883658170700073, 'step': 242},\n",
       "  {'loss': 0.22558653354644775, 'step': 243},\n",
       "  {'loss': 0.5056197643280029, 'step': 244},\n",
       "  {'loss': 0.8471188545227051, 'step': 245},\n",
       "  {'loss': 0.2872196435928345, 'step': 246},\n",
       "  {'loss': 0.5108844041824341, 'step': 247},\n",
       "  {'loss': 0.30972909927368164, 'step': 248},\n",
       "  {'loss': 0.421010285615921, 'step': 249},\n",
       "  {'loss': 1.030569314956665, 'step': 250},\n",
       "  {'loss': 0.735922634601593, 'step': 251},\n",
       "  {'loss': 0.3877575397491455, 'step': 252},\n",
       "  {'loss': 0.49810802936553955, 'step': 253},\n",
       "  {'loss': 0.1563035398721695, 'step': 254},\n",
       "  {'loss': 0.6865154504776001, 'step': 255},\n",
       "  {'loss': 0.40423643589019775, 'step': 256},\n",
       "  {'loss': 0.595611035823822, 'step': 257},\n",
       "  {'loss': 0.19640222191810608, 'step': 258},\n",
       "  {'loss': 0.7025160789489746, 'step': 259},\n",
       "  {'loss': 0.4472449719905853, 'step': 260},\n",
       "  {'loss': 1.5188592672348022, 'step': 261},\n",
       "  {'loss': 0.20247521996498108, 'step': 262},\n",
       "  {'loss': 0.15837982296943665, 'step': 263},\n",
       "  {'loss': 1.1693718433380127, 'step': 264},\n",
       "  {'loss': 1.3741527795791626, 'step': 265},\n",
       "  {'loss': 0.5574685335159302, 'step': 266},\n",
       "  {'loss': 0.13007009029388428, 'step': 267},\n",
       "  {'loss': 0.5993941426277161, 'step': 268},\n",
       "  {'loss': 0.7310990691184998, 'step': 269},\n",
       "  {'loss': 0.49847081303596497, 'step': 270},\n",
       "  {'loss': 1.3071357011795044, 'step': 271},\n",
       "  {'loss': 1.6010968685150146, 'step': 272},\n",
       "  {'loss': 1.0480560064315796, 'step': 273},\n",
       "  {'loss': 0.42054763436317444, 'step': 274},\n",
       "  {'loss': 0.395912766456604, 'step': 275},\n",
       "  {'loss': 0.7575664520263672, 'step': 276},\n",
       "  {'loss': 0.9352396726608276, 'step': 277},\n",
       "  {'loss': 0.35517218708992004, 'step': 278},\n",
       "  {'loss': 0.5626574158668518, 'step': 279},\n",
       "  {'loss': 0.9802314043045044, 'step': 280},\n",
       "  {'loss': 0.9616198539733887, 'step': 281},\n",
       "  {'loss': 0.7918515205383301, 'step': 282},\n",
       "  {'loss': 0.2049713134765625, 'step': 283},\n",
       "  {'loss': 0.19012749195098877, 'step': 284},\n",
       "  {'loss': 0.45540881156921387, 'step': 285},\n",
       "  {'loss': 0.6230193376541138, 'step': 286},\n",
       "  {'loss': 0.23365356028079987, 'step': 287},\n",
       "  {'loss': 0.7054982781410217, 'step': 288},\n",
       "  {'loss': 0.36718687415122986, 'step': 289},\n",
       "  {'loss': 0.5513582825660706, 'step': 290},\n",
       "  {'loss': 0.24126896262168884, 'step': 291},\n",
       "  {'loss': 0.449637770652771, 'step': 292},\n",
       "  {'loss': 0.5518311262130737, 'step': 293},\n",
       "  {'loss': 0.5722507238388062, 'step': 294},\n",
       "  {'loss': 0.19752852618694305, 'step': 295},\n",
       "  {'loss': 1.9203332662582397, 'step': 296},\n",
       "  {'loss': 0.403096079826355, 'step': 297},\n",
       "  {'loss': 0.18325471878051758, 'step': 298},\n",
       "  {'loss': 0.4119766652584076, 'step': 299},\n",
       "  {'loss': 0.4078090786933899, 'step': 300},\n",
       "  {'loss': 0.3553711175918579, 'step': 301},\n",
       "  {'loss': 0.302272766828537, 'step': 302},\n",
       "  {'loss': 0.19094474613666534, 'step': 303},\n",
       "  {'loss': 0.4763644337654114, 'step': 304},\n",
       "  {'loss': 0.1154051125049591, 'step': 305},\n",
       "  {'loss': 0.2042614072561264, 'step': 306},\n",
       "  {'loss': 0.7346655130386353, 'step': 307},\n",
       "  {'loss': 0.18094757199287415, 'step': 308},\n",
       "  {'loss': 2.497047185897827, 'step': 309},\n",
       "  {'loss': 0.5749641060829163, 'step': 310},\n",
       "  {'loss': 2.6026337146759033, 'step': 311},\n",
       "  {'loss': 0.1632612943649292, 'step': 312},\n",
       "  {'loss': 0.17654886841773987, 'step': 313},\n",
       "  {'loss': 1.2137497663497925, 'step': 314},\n",
       "  {'loss': 0.1997307986021042, 'step': 315},\n",
       "  {'loss': 0.5162487030029297, 'step': 316},\n",
       "  {'loss': 0.4987514019012451, 'step': 317},\n",
       "  {'loss': 0.6021601557731628, 'step': 318},\n",
       "  {'loss': 0.2352081835269928, 'step': 319},\n",
       "  {'loss': 1.3131952285766602, 'step': 320},\n",
       "  {'loss': 0.7006391882896423, 'step': 321},\n",
       "  {'loss': 0.3869467079639435, 'step': 322},\n",
       "  {'loss': 1.0647302865982056, 'step': 323},\n",
       "  {'loss': 0.5726331472396851, 'step': 324},\n",
       "  {'loss': 0.8575276732444763, 'step': 325},\n",
       "  {'loss': 0.6428574919700623, 'step': 326},\n",
       "  {'loss': 0.3458894193172455, 'step': 327},\n",
       "  {'loss': 0.5288723707199097, 'step': 328},\n",
       "  {'loss': 0.5313097238540649, 'step': 329},\n",
       "  {'loss': 1.1060054302215576, 'step': 330},\n",
       "  {'loss': 0.6066254377365112, 'step': 331},\n",
       "  {'loss': 1.053873062133789, 'step': 332},\n",
       "  {'loss': 1.1023701429367065, 'step': 333},\n",
       "  {'loss': 0.47014927864074707, 'step': 334},\n",
       "  {'loss': 0.6589318513870239, 'step': 335},\n",
       "  {'loss': 0.18022462725639343, 'step': 336},\n",
       "  {'loss': 0.2335195690393448, 'step': 337},\n",
       "  {'loss': 0.5754932761192322, 'step': 338},\n",
       "  {'loss': 0.47071853280067444, 'step': 339},\n",
       "  {'loss': 0.5408564805984497, 'step': 340},\n",
       "  {'loss': 0.9656692743301392, 'step': 341},\n",
       "  {'loss': 0.510353147983551, 'step': 342},\n",
       "  {'loss': 0.3377819061279297, 'step': 343},\n",
       "  {'loss': 0.652937650680542, 'step': 344},\n",
       "  {'loss': 0.650635838508606, 'step': 345},\n",
       "  {'loss': 0.3774528503417969, 'step': 346},\n",
       "  {'loss': 0.24704620242118835, 'step': 347},\n",
       "  {'loss': 0.2757568359375, 'step': 348},\n",
       "  {'loss': 0.21320094168186188, 'step': 349},\n",
       "  {'loss': 0.935754120349884, 'step': 350},\n",
       "  {'loss': 0.3465994894504547, 'step': 351},\n",
       "  {'loss': 0.27572327852249146, 'step': 352},\n",
       "  {'loss': 0.6810876131057739, 'step': 353},\n",
       "  {'loss': 0.3353387713432312, 'step': 354},\n",
       "  {'loss': 0.8277661204338074, 'step': 355},\n",
       "  {'loss': 0.8111134767532349, 'step': 356},\n",
       "  {'loss': 0.8734095096588135, 'step': 357},\n",
       "  {'loss': 0.11717107892036438, 'step': 358},\n",
       "  {'loss': 0.5444976091384888, 'step': 359},\n",
       "  {'loss': 0.5644450187683105, 'step': 360},\n",
       "  {'loss': 0.3489043712615967, 'step': 361},\n",
       "  {'loss': 0.2750976085662842, 'step': 362},\n",
       "  {'loss': 0.5763195157051086, 'step': 363},\n",
       "  {'loss': 0.3581945598125458, 'step': 364},\n",
       "  {'loss': 0.8238099217414856, 'step': 365},\n",
       "  {'loss': 0.3051624596118927, 'step': 366},\n",
       "  {'loss': 0.19078633189201355, 'step': 367},\n",
       "  {'loss': 0.6136864423751831, 'step': 368},\n",
       "  {'loss': 0.2651054263114929, 'step': 369},\n",
       "  {'loss': 0.37057599425315857, 'step': 370},\n",
       "  {'loss': 0.7388281226158142, 'step': 371},\n",
       "  {'loss': 0.44751179218292236, 'step': 372},\n",
       "  {'loss': 0.8401832580566406, 'step': 373},\n",
       "  {'loss': 0.20523443818092346, 'step': 374},\n",
       "  {'loss': 0.2301904559135437, 'step': 375},\n",
       "  {'loss': 0.6440820097923279, 'step': 376},\n",
       "  {'loss': 1.8449454307556152, 'step': 377},\n",
       "  {'loss': 1.036578893661499, 'step': 378},\n",
       "  {'loss': 0.7328762412071228, 'step': 379},\n",
       "  {'loss': 0.2625083029270172, 'step': 380},\n",
       "  {'loss': 0.3194921016693115, 'step': 381},\n",
       "  {'loss': 0.44614219665527344, 'step': 382},\n",
       "  {'loss': 0.24460271000862122, 'step': 383},\n",
       "  {'loss': 0.40125054121017456, 'step': 384},\n",
       "  {'loss': 0.34362372756004333, 'step': 385},\n",
       "  {'loss': 0.5994188785552979, 'step': 386},\n",
       "  {'loss': 0.4268304109573364, 'step': 387},\n",
       "  {'loss': 0.47245681285858154, 'step': 388},\n",
       "  {'loss': 0.26465117931365967, 'step': 389},\n",
       "  {'loss': 0.33938074111938477, 'step': 390},\n",
       "  {'loss': 0.5414757132530212, 'step': 391},\n",
       "  {'loss': 0.31680092215538025, 'step': 392},\n",
       "  {'loss': 0.895738422870636, 'step': 393},\n",
       "  {'loss': 0.9119101762771606, 'step': 394},\n",
       "  {'loss': 0.43388617038726807, 'step': 395},\n",
       "  {'loss': 0.5153470635414124, 'step': 396},\n",
       "  {'loss': 0.8606099486351013, 'step': 397},\n",
       "  {'loss': 0.46679508686065674, 'step': 398},\n",
       "  {'loss': 0.216483935713768, 'step': 399},\n",
       "  {'loss': 0.5547571182250977, 'step': 400},\n",
       "  {'loss': 0.5682460069656372, 'step': 401},\n",
       "  {'loss': 0.38449761271476746, 'step': 402},\n",
       "  {'loss': 0.24996288120746613, 'step': 403},\n",
       "  {'loss': 1.2886791229248047, 'step': 404},\n",
       "  {'loss': 0.26588982343673706, 'step': 405},\n",
       "  {'loss': 0.9031623601913452, 'step': 406},\n",
       "  {'loss': 0.4328041076660156, 'step': 407},\n",
       "  {'loss': 0.5129245519638062, 'step': 408},\n",
       "  {'loss': 0.6712547540664673, 'step': 409},\n",
       "  {'loss': 0.22176791727542877, 'step': 410},\n",
       "  {'loss': 0.5674916505813599, 'step': 411},\n",
       "  {'loss': 0.159491628408432, 'step': 412},\n",
       "  {'loss': 0.33420324325561523, 'step': 413},\n",
       "  {'loss': 0.35591059923171997, 'step': 414},\n",
       "  {'loss': 0.21535421907901764, 'step': 415},\n",
       "  {'loss': 0.4007503390312195, 'step': 416},\n",
       "  {'loss': 0.3851425349712372, 'step': 417},\n",
       "  {'loss': 0.24933283030986786, 'step': 418},\n",
       "  {'loss': 0.3656731843948364, 'step': 419},\n",
       "  {'loss': 1.028516411781311, 'step': 420},\n",
       "  {'loss': 0.30120420455932617, 'step': 421},\n",
       "  {'loss': 0.38199907541275024, 'step': 422},\n",
       "  {'loss': 0.12438227236270905, 'step': 423},\n",
       "  {'loss': 0.18985402584075928, 'step': 424},\n",
       "  {'loss': 0.30145177245140076, 'step': 425},\n",
       "  {'loss': 0.4203782081604004, 'step': 426},\n",
       "  {'loss': 0.4259772300720215, 'step': 427},\n",
       "  {'loss': 0.7463592290878296, 'step': 428},\n",
       "  {'loss': 0.4227105379104614, 'step': 429},\n",
       "  {'loss': 0.8143025040626526, 'step': 430},\n",
       "  {'loss': 0.2094762921333313, 'step': 431},\n",
       "  {'loss': 0.2281663566827774, 'step': 432},\n",
       "  {'loss': 0.35930705070495605, 'step': 433},\n",
       "  {'loss': 0.6017696857452393, 'step': 434},\n",
       "  {'loss': 0.39079779386520386, 'step': 435},\n",
       "  {'loss': 0.45158132910728455, 'step': 436},\n",
       "  {'loss': 0.9862222671508789, 'step': 437},\n",
       "  {'loss': 0.7357494831085205, 'step': 438},\n",
       "  {'loss': 0.1990564614534378, 'step': 439},\n",
       "  {'loss': 0.378248393535614, 'step': 440},\n",
       "  {'loss': 0.6205928921699524, 'step': 441},\n",
       "  {'loss': 0.7002726793289185, 'step': 442},\n",
       "  {'loss': 0.251923531293869, 'step': 443},\n",
       "  {'loss': 0.3369855582714081, 'step': 444},\n",
       "  {'loss': 0.439601868391037, 'step': 445},\n",
       "  {'loss': 0.6442088484764099, 'step': 446},\n",
       "  {'loss': 0.2626216411590576, 'step': 447},\n",
       "  {'loss': 0.7570586800575256, 'step': 448},\n",
       "  {'loss': 0.33119678497314453, 'step': 449},\n",
       "  {'loss': 0.4362950026988983, 'step': 450},\n",
       "  {'loss': 0.8520157337188721, 'step': 451},\n",
       "  {'loss': 0.45624297857284546, 'step': 452},\n",
       "  {'loss': 0.9639805555343628, 'step': 453},\n",
       "  {'loss': 0.2588694095611572, 'step': 454},\n",
       "  {'loss': 0.4534216821193695, 'step': 455},\n",
       "  {'loss': 0.5925999283790588, 'step': 456},\n",
       "  {'loss': 0.18417397141456604, 'step': 457},\n",
       "  {'loss': 0.7885212302207947, 'step': 458},\n",
       "  {'loss': 0.7691371440887451, 'step': 459},\n",
       "  {'loss': 0.22174103558063507, 'step': 460},\n",
       "  {'loss': 0.21113133430480957, 'step': 461},\n",
       "  {'loss': 0.16321739554405212, 'step': 462},\n",
       "  {'loss': 0.318045437335968, 'step': 463},\n",
       "  {'loss': 0.2898678481578827, 'step': 464},\n",
       "  {'loss': 1.1915485858917236, 'step': 465},\n",
       "  {'loss': 0.5680764317512512, 'step': 466},\n",
       "  {'loss': 0.518136739730835, 'step': 467},\n",
       "  {'loss': 0.5836379528045654, 'step': 468},\n",
       "  {'loss': 0.5042408108711243, 'step': 469},\n",
       "  {'loss': 0.48005276918411255, 'step': 470},\n",
       "  {'loss': 0.3619910478591919, 'step': 471},\n",
       "  {'loss': 0.2981373965740204, 'step': 472},\n",
       "  {'loss': 0.7540152072906494, 'step': 473},\n",
       "  {'loss': 0.3645312488079071, 'step': 474},\n",
       "  {'loss': 0.3131873905658722, 'step': 475},\n",
       "  {'loss': 0.37975892424583435, 'step': 476},\n",
       "  {'loss': 0.5216178894042969, 'step': 477},\n",
       "  {'loss': 0.5347753763198853, 'step': 478},\n",
       "  {'loss': 0.3095475435256958, 'step': 479},\n",
       "  {'loss': 0.15367469191551208, 'step': 480},\n",
       "  {'loss': 0.7877160310745239, 'step': 481},\n",
       "  {'loss': 0.3822793662548065, 'step': 482},\n",
       "  {'loss': 0.35029101371765137, 'step': 483},\n",
       "  {'loss': 0.33389049768447876, 'step': 484},\n",
       "  {'loss': 0.8272383213043213, 'step': 485},\n",
       "  {'loss': 0.9027242660522461, 'step': 486},\n",
       "  {'loss': 0.839789628982544, 'step': 487},\n",
       "  {'loss': 0.5772409439086914, 'step': 488},\n",
       "  {'loss': 0.5267437696456909, 'step': 489},\n",
       "  {'loss': 0.5128551125526428, 'step': 490},\n",
       "  {'loss': 0.4457666873931885, 'step': 491},\n",
       "  {'loss': 0.29159826040267944, 'step': 492},\n",
       "  {'loss': 0.39060676097869873, 'step': 493},\n",
       "  {'loss': 0.15015247464179993, 'step': 494},\n",
       "  {'loss': 0.3807871341705322, 'step': 495},\n",
       "  {'loss': 0.26563334465026855, 'step': 496},\n",
       "  {'loss': 0.3519344925880432, 'step': 497},\n",
       "  {'loss': 0.16545169055461884, 'step': 498},\n",
       "  {'loss': 0.39073437452316284, 'step': 499},\n",
       "  {'loss': 0.2791999280452728, 'step': 500},\n",
       "  {'loss': 0.16255688667297363, 'step': 501},\n",
       "  {'loss': 0.9552596807479858, 'step': 502},\n",
       "  {'loss': 0.4454353153705597, 'step': 503},\n",
       "  {'loss': 0.7225263714790344, 'step': 504},\n",
       "  {'loss': 0.10979211330413818, 'step': 505},\n",
       "  {'loss': 0.32266005873680115, 'step': 506},\n",
       "  {'loss': 0.5743387341499329, 'step': 507},\n",
       "  {'loss': 0.25991255044937134, 'step': 508},\n",
       "  {'loss': 0.45065876841545105, 'step': 509},\n",
       "  {'loss': 0.4522002637386322, 'step': 510},\n",
       "  {'loss': 0.2894139885902405, 'step': 511},\n",
       "  {'loss': 0.49308282136917114, 'step': 512},\n",
       "  {'loss': 0.4509868323802948, 'step': 513},\n",
       "  {'loss': 0.1279904544353485, 'step': 514},\n",
       "  {'loss': 0.5536773800849915, 'step': 515},\n",
       "  {'loss': 0.3481646776199341, 'step': 516},\n",
       "  {'loss': 0.4140262007713318, 'step': 517},\n",
       "  {'loss': 0.3988600969314575, 'step': 518},\n",
       "  {'loss': 0.3085368573665619, 'step': 519},\n",
       "  {'loss': 1.073426604270935, 'step': 520},\n",
       "  {'loss': 0.47349250316619873, 'step': 521},\n",
       "  {'loss': 0.3472113013267517, 'step': 522},\n",
       "  {'loss': 0.22753401100635529, 'step': 523},\n",
       "  {'loss': 0.6834784746170044, 'step': 524},\n",
       "  {'loss': 0.3454751968383789, 'step': 525},\n",
       "  {'loss': 0.3185725808143616, 'step': 526},\n",
       "  {'loss': 0.6098261475563049, 'step': 527},\n",
       "  {'loss': 0.5006214380264282, 'step': 528},\n",
       "  {'loss': 0.3458535075187683, 'step': 529},\n",
       "  {'loss': 0.2230641394853592, 'step': 530},\n",
       "  {'loss': 0.46014678478240967, 'step': 531},\n",
       "  {'loss': 0.15581455826759338, 'step': 532},\n",
       "  {'loss': 0.24020616710186005, 'step': 533},\n",
       "  {'loss': 0.21347710490226746, 'step': 534},\n",
       "  {'loss': 0.4476562440395355, 'step': 535},\n",
       "  {'loss': 0.6378531455993652, 'step': 536},\n",
       "  {'loss': 0.6270928978919983, 'step': 537},\n",
       "  {'loss': 0.3729284703731537, 'step': 538},\n",
       "  {'loss': 0.22143392264842987, 'step': 539},\n",
       "  {'loss': 0.46755051612854004, 'step': 540},\n",
       "  {'loss': 0.24471406638622284, 'step': 541},\n",
       "  {'loss': 0.7244612574577332, 'step': 542},\n",
       "  {'loss': 0.6019488573074341, 'step': 543},\n",
       "  {'loss': 0.4286908209323883, 'step': 544},\n",
       "  {'loss': 0.25909045338630676, 'step': 545},\n",
       "  {'loss': 0.27381619811058044, 'step': 546},\n",
       "  {'loss': 0.8751187920570374, 'step': 547},\n",
       "  {'loss': 0.44370973110198975, 'step': 548},\n",
       "  {'loss': 0.14544923603534698, 'step': 549},\n",
       "  {'loss': 0.2851189076900482, 'step': 550},\n",
       "  {'loss': 0.26010701060295105, 'step': 551},\n",
       "  {'loss': 0.12975233793258667, 'step': 552},\n",
       "  {'loss': 0.41578733921051025, 'step': 553},\n",
       "  {'loss': 0.7034786343574524, 'step': 554},\n",
       "  {'loss': 0.33864980936050415, 'step': 555},\n",
       "  {'loss': 1.6358815431594849, 'step': 556},\n",
       "  {'loss': 0.3351278305053711, 'step': 557},\n",
       "  {'loss': 0.4346269369125366, 'step': 558},\n",
       "  {'loss': 0.1433415710926056, 'step': 559},\n",
       "  {'loss': 0.2811397910118103, 'step': 560},\n",
       "  {'loss': 0.811860203742981, 'step': 561},\n",
       "  {'loss': 0.3305031657218933, 'step': 562},\n",
       "  {'loss': 0.2881680130958557, 'step': 563},\n",
       "  {'loss': 0.604872465133667, 'step': 564},\n",
       "  {'loss': 0.810741662979126, 'step': 565},\n",
       "  {'loss': 0.21156413853168488, 'step': 566},\n",
       "  {'loss': 1.0867154598236084, 'step': 567},\n",
       "  {'loss': 0.627912163734436, 'step': 568},\n",
       "  {'loss': 0.6663510799407959, 'step': 569},\n",
       "  {'loss': 0.34928786754608154, 'step': 570},\n",
       "  {'loss': 1.207646369934082, 'step': 571},\n",
       "  {'loss': 0.22211255133152008, 'step': 572},\n",
       "  {'loss': 0.27082669734954834, 'step': 573},\n",
       "  {'loss': 0.4498966634273529, 'step': 574},\n",
       "  {'loss': 1.2177311182022095, 'step': 575},\n",
       "  {'loss': 0.27643781900405884, 'step': 576},\n",
       "  {'loss': 0.6909878253936768, 'step': 577},\n",
       "  {'loss': 0.24152952432632446, 'step': 578},\n",
       "  {'loss': 0.2779705822467804, 'step': 579},\n",
       "  {'loss': 0.5319942235946655, 'step': 580},\n",
       "  {'loss': 1.2718384265899658, 'step': 581},\n",
       "  {'loss': 0.7724388241767883, 'step': 582},\n",
       "  {'loss': 0.18166840076446533, 'step': 583},\n",
       "  {'loss': 0.30710387229919434, 'step': 584},\n",
       "  {'loss': 1.0061684846878052, 'step': 585},\n",
       "  {'loss': 0.296494722366333, 'step': 586},\n",
       "  {'loss': 0.2946861684322357, 'step': 587},\n",
       "  {'loss': 0.29213079810142517, 'step': 588},\n",
       "  {'loss': 0.28421786427497864, 'step': 589},\n",
       "  {'loss': 0.6091217398643494, 'step': 590},\n",
       "  {'loss': 1.1787526607513428, 'step': 591},\n",
       "  {'loss': 0.5325121283531189, 'step': 592},\n",
       "  {'loss': 0.3904987871646881, 'step': 593},\n",
       "  {'loss': 0.46611785888671875, 'step': 594},\n",
       "  {'loss': 0.28113484382629395, 'step': 595},\n",
       "  {'loss': 0.18201838433742523, 'step': 596},\n",
       "  {'loss': 0.2535558342933655, 'step': 597},\n",
       "  {'loss': 0.7442786693572998, 'step': 598},\n",
       "  {'loss': 0.2731836438179016, 'step': 599},\n",
       "  {'loss': 0.539148211479187, 'step': 600},\n",
       "  {'loss': 0.5688554048538208, 'step': 601},\n",
       "  {'loss': 0.09242827445268631, 'step': 602},\n",
       "  {'loss': 0.1815551370382309, 'step': 603},\n",
       "  {'loss': 0.4538103938102722, 'step': 604},\n",
       "  {'loss': 0.162394180893898, 'step': 605},\n",
       "  {'loss': 0.23192718625068665, 'step': 606},\n",
       "  {'loss': 0.44663047790527344, 'step': 607},\n",
       "  {'loss': 0.4154953360557556, 'step': 608},\n",
       "  {'loss': 0.45264941453933716, 'step': 609},\n",
       "  {'loss': 0.16430650651454926, 'step': 610},\n",
       "  {'loss': 0.42799511551856995, 'step': 611},\n",
       "  {'loss': 0.15477001667022705, 'step': 612},\n",
       "  {'loss': 0.7346514463424683, 'step': 613},\n",
       "  {'loss': 0.09923853725194931, 'step': 614},\n",
       "  {'loss': 0.9061040878295898, 'step': 615},\n",
       "  {'loss': 0.5092154741287231, 'step': 616},\n",
       "  {'loss': 0.4488159418106079, 'step': 617},\n",
       "  {'loss': 0.41395580768585205, 'step': 618},\n",
       "  {'loss': 0.5754734873771667, 'step': 619},\n",
       "  {'loss': 0.3916420340538025, 'step': 620},\n",
       "  {'loss': 0.7157875895500183, 'step': 621},\n",
       "  {'loss': 0.9900479316711426, 'step': 622},\n",
       "  {'loss': 0.14707890152931213, 'step': 623},\n",
       "  {'loss': 0.24541090428829193, 'step': 624},\n",
       "  {'loss': 1.0521318912506104, 'step': 625},\n",
       "  {'loss': 0.6945500373840332, 'step': 626},\n",
       "  {'loss': 0.4088391065597534, 'step': 627},\n",
       "  {'loss': 0.16404619812965393, 'step': 628},\n",
       "  {'loss': 0.5372800230979919, 'step': 629},\n",
       "  {'loss': 0.4578952193260193, 'step': 630},\n",
       "  {'loss': 0.21768160164356232, 'step': 631},\n",
       "  {'loss': 0.46109288930892944, 'step': 632},\n",
       "  {'loss': 0.37755510210990906, 'step': 633},\n",
       "  {'loss': 0.4203220009803772, 'step': 634},\n",
       "  {'loss': 0.49557751417160034, 'step': 635},\n",
       "  {'loss': 0.1680847853422165, 'step': 636},\n",
       "  {'loss': 0.3489692211151123, 'step': 637},\n",
       "  {'loss': 0.4685596525669098, 'step': 638},\n",
       "  {'loss': 0.21977031230926514, 'step': 639},\n",
       "  {'loss': 0.33735889196395874, 'step': 640},\n",
       "  {'loss': 0.29505836963653564, 'step': 641},\n",
       "  {'loss': 0.5941318273544312, 'step': 642},\n",
       "  {'loss': 0.3295917510986328, 'step': 643},\n",
       "  {'loss': 0.2605920433998108, 'step': 644},\n",
       "  {'loss': 0.5048933029174805, 'step': 645},\n",
       "  {'loss': 0.505142092704773, 'step': 646},\n",
       "  {'loss': 0.253167062997818, 'step': 647},\n",
       "  {'loss': 0.3341386914253235, 'step': 648},\n",
       "  {'loss': 0.8997882008552551, 'step': 649},\n",
       "  {'loss': 0.5445303916931152, 'step': 650},\n",
       "  {'loss': 0.5074512958526611, 'step': 651},\n",
       "  {'loss': 0.6015803217887878, 'step': 652},\n",
       "  {'loss': 0.33335670828819275, 'step': 653},\n",
       "  {'loss': 0.26705050468444824, 'step': 654},\n",
       "  {'loss': 0.32755452394485474, 'step': 655},\n",
       "  {'loss': 0.6089528799057007, 'step': 656},\n",
       "  {'loss': 0.22581344842910767, 'step': 657},\n",
       "  {'loss': 0.8938563466072083, 'step': 658},\n",
       "  {'loss': 0.267334520816803, 'step': 659},\n",
       "  {'loss': 0.3139697313308716, 'step': 660},\n",
       "  {'loss': 1.1344127655029297, 'step': 661},\n",
       "  {'loss': 0.41559088230133057, 'step': 662},\n",
       "  {'loss': 0.4004722237586975, 'step': 663},\n",
       "  {'loss': 0.25853997468948364, 'step': 664},\n",
       "  {'loss': 0.23936842381954193, 'step': 665},\n",
       "  {'loss': 0.14090996980667114, 'step': 666},\n",
       "  {'loss': 0.63338303565979, 'step': 667},\n",
       "  {'loss': 0.4735708236694336, 'step': 668},\n",
       "  {'loss': 0.3934774398803711, 'step': 669},\n",
       "  {'loss': 46.888946533203125, 'step': 670},\n",
       "  {'loss': 1.0732501745224, 'step': 671},\n",
       "  {'loss': 0.27054309844970703, 'step': 672},\n",
       "  {'loss': 0.27201032638549805, 'step': 673},\n",
       "  {'loss': 0.8087447881698608, 'step': 674},\n",
       "  {'loss': 0.7525973320007324, 'step': 675},\n",
       "  {'loss': 0.5477948188781738, 'step': 676},\n",
       "  {'loss': 0.900260329246521, 'step': 677},\n",
       "  {'loss': 0.698767900466919, 'step': 678},\n",
       "  {'loss': 2.794379711151123, 'step': 679},\n",
       "  {'loss': 0.5538232326507568, 'step': 680},\n",
       "  {'loss': 0.5288207530975342, 'step': 681},\n",
       "  {'loss': 0.6197229623794556, 'step': 682},\n",
       "  {'loss': 0.9686732292175293, 'step': 683},\n",
       "  {'loss': 0.8194608092308044, 'step': 684},\n",
       "  {'loss': 0.7860667705535889, 'step': 685},\n",
       "  {'loss': 1.570731520652771, 'step': 686},\n",
       "  {'loss': 0.5777188539505005, 'step': 687},\n",
       "  {'loss': 1.2157790660858154, 'step': 688},\n",
       "  {'loss': 0.629981279373169, 'step': 689},\n",
       "  {'loss': 0.9217123985290527, 'step': 690},\n",
       "  {'loss': 0.4069730043411255, 'step': 691},\n",
       "  {'loss': 0.4585963785648346, 'step': 692},\n",
       "  {'loss': 0.5538475513458252, 'step': 693},\n",
       "  {'loss': 0.7940462827682495, 'step': 694},\n",
       "  {'loss': 0.20064455270767212, 'step': 695},\n",
       "  {'loss': 0.6715295314788818, 'step': 696},\n",
       "  {'loss': 0.8083294630050659, 'step': 697},\n",
       "  {'loss': 0.5649280548095703, 'step': 698},\n",
       "  {'loss': 0.25100332498550415, 'step': 699},\n",
       "  {'loss': 0.3548595905303955, 'step': 700},\n",
       "  {'loss': 0.38459959626197815, 'step': 701},\n",
       "  {'loss': 0.6547396183013916, 'step': 702},\n",
       "  {'loss': 0.8111290335655212, 'step': 703},\n",
       "  {'loss': 1.0784237384796143, 'step': 704},\n",
       "  {'loss': 0.8086755275726318, 'step': 705},\n",
       "  {'loss': 0.3080756962299347, 'step': 706},\n",
       "  {'loss': 0.6916882991790771, 'step': 707},\n",
       "  {'loss': 0.5745193958282471, 'step': 708},\n",
       "  {'loss': 0.3625430464744568, 'step': 709},\n",
       "  {'loss': 0.2896903455257416, 'step': 710},\n",
       "  {'loss': 1.2275328636169434, 'step': 711},\n",
       "  {'loss': 0.1856117844581604, 'step': 712},\n",
       "  {'loss': 0.35164570808410645, 'step': 713},\n",
       "  {'loss': 1.0215063095092773, 'step': 714},\n",
       "  {'loss': 0.3510807156562805, 'step': 715},\n",
       "  {'loss': 0.19554050266742706, 'step': 716},\n",
       "  {'loss': 0.7437299489974976, 'step': 717},\n",
       "  {'loss': 0.30211204290390015, 'step': 718},\n",
       "  {'loss': 0.2539762556552887, 'step': 719},\n",
       "  {'loss': 0.47621792554855347, 'step': 720},\n",
       "  {'loss': 0.8661994934082031, 'step': 721},\n",
       "  {'loss': 0.23807431757450104, 'step': 722},\n",
       "  {'loss': 0.4968159794807434, 'step': 723},\n",
       "  {'loss': 0.47713080048561096, 'step': 724},\n",
       "  {'loss': 0.2444976568222046, 'step': 725},\n",
       "  {'loss': 0.5440919399261475, 'step': 726},\n",
       "  {'loss': 0.23033498227596283, 'step': 727},\n",
       "  {'loss': 0.19950644671916962, 'step': 728},\n",
       "  {'loss': 0.20768842101097107, 'step': 729},\n",
       "  {'loss': 0.5231348872184753, 'step': 730},\n",
       "  {'loss': 0.1990266740322113, 'step': 731},\n",
       "  {'loss': 0.6566982269287109, 'step': 732},\n",
       "  {'loss': 0.8806062340736389, 'step': 733},\n",
       "  {'loss': 1.078637957572937, 'step': 734},\n",
       "  {'loss': 0.5366725921630859, 'step': 735},\n",
       "  {'loss': 0.24159935116767883, 'step': 736},\n",
       "  {'loss': 0.20983782410621643, 'step': 737},\n",
       "  {'loss': 0.29949095845222473, 'step': 738},\n",
       "  {'loss': 1.0466282367706299, 'step': 739},\n",
       "  {'loss': 0.22692379355430603, 'step': 740},\n",
       "  {'loss': 1.4629817008972168, 'step': 741},\n",
       "  {'loss': 0.23549070954322815, 'step': 742},\n",
       "  {'loss': 0.40705516934394836, 'step': 743},\n",
       "  {'loss': 0.7875417470932007, 'step': 744},\n",
       "  {'loss': 1.9798579216003418, 'step': 745},\n",
       "  {'loss': 0.22494427859783173, 'step': 746},\n",
       "  {'loss': 1.305248737335205, 'step': 747},\n",
       "  {'loss': 0.1893712878227234, 'step': 748},\n",
       "  {'loss': 0.8589667677879333, 'step': 749},\n",
       "  {'loss': 0.4733981490135193, 'step': 750},\n",
       "  {'loss': 0.4105634093284607, 'step': 751},\n",
       "  {'loss': 0.1783904880285263, 'step': 752},\n",
       "  {'loss': 0.36283352971076965, 'step': 753},\n",
       "  {'loss': 0.9730226397514343, 'step': 754},\n",
       "  {'loss': 1.0765442848205566, 'step': 755},\n",
       "  {'loss': 0.43059954047203064, 'step': 756},\n",
       "  {'loss': 0.38073819875717163, 'step': 757},\n",
       "  {'loss': 0.5814290046691895, 'step': 758},\n",
       "  {'loss': 0.4515489339828491, 'step': 759},\n",
       "  {'loss': 1.1214240789413452, 'step': 760},\n",
       "  {'loss': 0.4007510542869568, 'step': 761},\n",
       "  {'loss': 0.7025720477104187, 'step': 762},\n",
       "  {'loss': 1.5136492252349854, 'step': 763},\n",
       "  {'loss': 0.54767245054245, 'step': 764},\n",
       "  {'loss': 0.6391621828079224, 'step': 765},\n",
       "  {'loss': 0.32249879837036133, 'step': 766},\n",
       "  {'loss': 0.6018762588500977, 'step': 767},\n",
       "  {'loss': 0.5983371734619141, 'step': 768},\n",
       "  {'loss': 1.252996563911438, 'step': 769},\n",
       "  {'loss': 0.3918378949165344, 'step': 770},\n",
       "  {'loss': 1.2745754718780518, 'step': 771},\n",
       "  {'loss': 0.19735568761825562, 'step': 772},\n",
       "  {'loss': 0.2507129907608032, 'step': 773},\n",
       "  {'loss': 0.3907221555709839, 'step': 774},\n",
       "  {'loss': 0.4749293327331543, 'step': 775},\n",
       "  {'loss': 0.3086577355861664, 'step': 776},\n",
       "  {'loss': 0.22068659961223602, 'step': 777},\n",
       "  {'loss': 1.1009190082550049, 'step': 778},\n",
       "  {'loss': 0.41766661405563354, 'step': 779},\n",
       "  {'loss': 0.23951342701911926, 'step': 780},\n",
       "  {'loss': 0.9822545051574707, 'step': 781},\n",
       "  {'loss': 1.1720542907714844, 'step': 782},\n",
       "  {'loss': 0.3271808922290802, 'step': 783},\n",
       "  {'loss': 0.35059770941734314, 'step': 784},\n",
       "  {'loss': 0.2817556858062744, 'step': 785},\n",
       "  {'loss': 0.8554793000221252, 'step': 786},\n",
       "  {'loss': 0.9414270520210266, 'step': 787},\n",
       "  {'loss': 0.32615894079208374, 'step': 788},\n",
       "  {'loss': 0.09938349574804306, 'step': 789},\n",
       "  {'loss': 0.27981114387512207, 'step': 790},\n",
       "  {'loss': 1.0093703269958496, 'step': 791},\n",
       "  {'loss': 0.9263741970062256, 'step': 792},\n",
       "  {'loss': 1.4255988597869873, 'step': 793},\n",
       "  {'loss': 0.26300162076950073, 'step': 794},\n",
       "  {'loss': 0.4751228094100952, 'step': 795},\n",
       "  {'loss': 0.4139503836631775, 'step': 796},\n",
       "  {'loss': 0.4683874547481537, 'step': 797},\n",
       "  {'loss': 0.09525015205144882, 'step': 798},\n",
       "  {'loss': 0.7346996665000916, 'step': 799},\n",
       "  {'loss': 0.41295385360717773, 'step': 800},\n",
       "  {'loss': 0.21656739711761475, 'step': 801},\n",
       "  {'loss': 0.31157052516937256, 'step': 802},\n",
       "  {'loss': 0.44396471977233887, 'step': 803},\n",
       "  {'loss': 0.27911707758903503, 'step': 804},\n",
       "  {'loss': 0.43689972162246704, 'step': 805},\n",
       "  {'loss': 1.1167125701904297, 'step': 806},\n",
       "  {'loss': 0.7972558736801147, 'step': 807},\n",
       "  {'loss': 0.1764114648103714, 'step': 808},\n",
       "  {'loss': 1.0511858463287354, 'step': 809},\n",
       "  {'loss': 0.28652679920196533, 'step': 810},\n",
       "  {'loss': 0.26916414499282837, 'step': 811},\n",
       "  {'loss': 0.23527327179908752, 'step': 812},\n",
       "  {'loss': 0.2956655025482178, 'step': 813},\n",
       "  {'loss': 0.23595157265663147, 'step': 814},\n",
       "  {'loss': 0.5045892000198364, 'step': 815},\n",
       "  {'loss': 0.2260083258152008, 'step': 816},\n",
       "  {'loss': 0.45703035593032837, 'step': 817},\n",
       "  {'loss': 0.9773216247558594, 'step': 818},\n",
       "  {'loss': 1.0356614589691162, 'step': 819},\n",
       "  {'loss': 0.24820077419281006, 'step': 820},\n",
       "  {'loss': 0.6266024112701416, 'step': 821},\n",
       "  {'loss': 0.8457026481628418, 'step': 822},\n",
       "  {'loss': 0.45031359791755676, 'step': 823},\n",
       "  {'loss': 0.38595980405807495, 'step': 824},\n",
       "  {'loss': 0.2849326729774475, 'step': 825},\n",
       "  {'loss': 0.5450382828712463, 'step': 826},\n",
       "  {'loss': 0.304973304271698, 'step': 827},\n",
       "  {'loss': 0.30364152789115906, 'step': 828},\n",
       "  {'loss': 0.7393465042114258, 'step': 829},\n",
       "  {'loss': 0.557282567024231, 'step': 830},\n",
       "  {'loss': 0.34332549571990967, 'step': 831},\n",
       "  {'loss': 0.29367125034332275, 'step': 832},\n",
       "  {'loss': 0.6127622127532959, 'step': 833},\n",
       "  {'loss': 0.26606041193008423, 'step': 834},\n",
       "  {'loss': 0.30778127908706665, 'step': 835},\n",
       "  {'loss': 0.4983956813812256, 'step': 836},\n",
       "  {'loss': 0.7189865112304688, 'step': 837},\n",
       "  {'loss': 0.505950927734375, 'step': 838},\n",
       "  {'loss': 0.19822609424591064, 'step': 839},\n",
       "  {'loss': 0.284879207611084, 'step': 840},\n",
       "  {'loss': 0.591340184211731, 'step': 841},\n",
       "  {'loss': 0.5436779260635376, 'step': 842},\n",
       "  {'loss': 0.21086320281028748, 'step': 843},\n",
       "  {'loss': 0.3018728792667389, 'step': 844},\n",
       "  {'loss': 0.217201367020607, 'step': 845},\n",
       "  {'loss': 0.5466843247413635, 'step': 846},\n",
       "  {'loss': 0.28852730989456177, 'step': 847},\n",
       "  {'loss': 0.7412900328636169, 'step': 848},\n",
       "  {'loss': 0.4795381426811218, 'step': 849},\n",
       "  {'loss': 0.7045472264289856, 'step': 850},\n",
       "  {'loss': 0.326690673828125, 'step': 851},\n",
       "  {'loss': 0.8571836352348328, 'step': 852},\n",
       "  {'loss': 0.5533291101455688, 'step': 853},\n",
       "  {'loss': 0.5429757833480835, 'step': 854},\n",
       "  {'loss': 0.5068215727806091, 'step': 855},\n",
       "  {'loss': 0.3757779598236084, 'step': 856},\n",
       "  {'loss': 0.8555880784988403, 'step': 857},\n",
       "  {'loss': 0.21509778499603271, 'step': 858},\n",
       "  {'loss': 0.6654505133628845, 'step': 859},\n",
       "  {'loss': 0.44471246004104614, 'step': 860},\n",
       "  {'loss': 0.4593110680580139, 'step': 861},\n",
       "  {'loss': 1.064575433731079, 'step': 862},\n",
       "  {'loss': 1.1732027530670166, 'step': 863},\n",
       "  {'loss': 0.8339635729789734, 'step': 864},\n",
       "  {'loss': 0.12845730781555176, 'step': 865},\n",
       "  {'loss': 0.36490732431411743, 'step': 866},\n",
       "  {'loss': 0.4013622999191284, 'step': 867},\n",
       "  {'loss': 0.3015880286693573, 'step': 868},\n",
       "  {'loss': 0.25643742084503174, 'step': 869},\n",
       "  {'loss': 0.18827781081199646, 'step': 870},\n",
       "  {'loss': 0.4131448268890381, 'step': 871},\n",
       "  {'loss': 0.19834038615226746, 'step': 872},\n",
       "  {'loss': 0.21143878996372223, 'step': 873},\n",
       "  {'loss': 0.5373768210411072, 'step': 874},\n",
       "  {'loss': 0.10183310508728027, 'step': 875},\n",
       "  {'loss': 0.4045637249946594, 'step': 876},\n",
       "  {'loss': 0.680784285068512, 'step': 877},\n",
       "  {'loss': 0.24786756932735443, 'step': 878},\n",
       "  {'loss': 3.475344181060791, 'step': 879},\n",
       "  {'loss': 0.7458071708679199, 'step': 880},\n",
       "  {'loss': 0.9165699481964111, 'step': 881},\n",
       "  {'loss': 0.19914878904819489, 'step': 882},\n",
       "  {'loss': 0.463785856962204, 'step': 883},\n",
       "  {'loss': 0.7953962087631226, 'step': 884},\n",
       "  {'loss': 0.3961073160171509, 'step': 885},\n",
       "  {'loss': 0.2303832769393921, 'step': 886},\n",
       "  {'loss': 1.0479695796966553, 'step': 887},\n",
       "  {'loss': 0.277007520198822, 'step': 888},\n",
       "  {'loss': 0.3657532334327698, 'step': 889},\n",
       "  {'loss': 0.38991615176200867, 'step': 890},\n",
       "  {'loss': 0.6338413953781128, 'step': 891},\n",
       "  {'loss': 0.33264222741127014, 'step': 892},\n",
       "  {'loss': 1.199231743812561, 'step': 893},\n",
       "  {'loss': 0.3052959144115448, 'step': 894},\n",
       "  {'loss': 0.342886745929718, 'step': 895},\n",
       "  {'loss': 0.5543808341026306, 'step': 896},\n",
       "  {'loss': 0.36828041076660156, 'step': 897},\n",
       "  {'loss': 0.23111861944198608, 'step': 898},\n",
       "  {'loss': 0.2650514841079712, 'step': 899},\n",
       "  {'loss': 0.21200314164161682, 'step': 900},\n",
       "  {'loss': 0.6876190900802612, 'step': 901},\n",
       "  {'loss': 0.33756107091903687, 'step': 902},\n",
       "  {'loss': 0.17926108837127686, 'step': 903},\n",
       "  {'loss': 0.24012985825538635, 'step': 904},\n",
       "  {'loss': 0.4314088821411133, 'step': 905},\n",
       "  {'loss': 0.5921704173088074, 'step': 906},\n",
       "  {'loss': 0.5883157849311829, 'step': 907},\n",
       "  {'loss': 0.3370932340621948, 'step': 908},\n",
       "  {'loss': 0.14253515005111694, 'step': 909},\n",
       "  {'loss': 0.6739569902420044, 'step': 910},\n",
       "  {'loss': 0.11782488226890564, 'step': 911},\n",
       "  {'loss': 0.6823491454124451, 'step': 912},\n",
       "  {'loss': 0.4804673492908478, 'step': 913},\n",
       "  {'loss': 0.8595017194747925, 'step': 914},\n",
       "  {'loss': 0.1288592666387558, 'step': 915},\n",
       "  {'loss': 1.3323311805725098, 'step': 916},\n",
       "  {'loss': 0.2784389853477478, 'step': 917},\n",
       "  {'loss': 0.7118095755577087, 'step': 918},\n",
       "  {'loss': 0.4833540916442871, 'step': 919},\n",
       "  {'loss': 0.217390775680542, 'step': 920},\n",
       "  {'loss': 1.04468834400177, 'step': 921},\n",
       "  {'loss': 0.21982204914093018, 'step': 922},\n",
       "  {'loss': 0.5164662003517151, 'step': 923},\n",
       "  {'loss': 0.2940818667411804, 'step': 924},\n",
       "  {'loss': 0.2999488115310669, 'step': 925},\n",
       "  {'loss': 0.9145219922065735, 'step': 926},\n",
       "  {'loss': 0.33245232701301575, 'step': 927},\n",
       "  {'loss': 0.1665237843990326, 'step': 928},\n",
       "  {'loss': 1.0821588039398193, 'step': 929},\n",
       "  {'loss': 0.3657441735267639, 'step': 930},\n",
       "  {'loss': 0.6666605472564697, 'step': 931},\n",
       "  {'loss': 0.49390536546707153, 'step': 932},\n",
       "  {'loss': 0.28231513500213623, 'step': 933},\n",
       "  {'loss': 0.8986069560050964, 'step': 934},\n",
       "  {'loss': 0.4440525770187378, 'step': 935},\n",
       "  {'loss': 0.6429922580718994, 'step': 936},\n",
       "  {'loss': 0.2922760248184204, 'step': 937},\n",
       "  {'loss': 0.26263079047203064, 'step': 938},\n",
       "  {'loss': 0.6443785429000854, 'step': 939},\n",
       "  {'loss': 0.73885577917099, 'step': 940},\n",
       "  {'loss': 0.4163680672645569, 'step': 941},\n",
       "  {'loss': 0.2649039924144745, 'step': 942},\n",
       "  {'loss': 0.6600992679595947, 'step': 943},\n",
       "  {'loss': 0.4457371234893799, 'step': 944},\n",
       "  {'loss': 0.2517113983631134, 'step': 945},\n",
       "  {'loss': 0.8195933699607849, 'step': 946},\n",
       "  {'loss': 0.22753360867500305, 'step': 947},\n",
       "  {'loss': 0.6811363697052002, 'step': 948},\n",
       "  {'loss': 0.6265959739685059, 'step': 949},\n",
       "  {'loss': 0.8916258811950684, 'step': 950},\n",
       "  {'loss': 1.489350438117981, 'step': 951},\n",
       "  {'loss': 0.8062402009963989, 'step': 952},\n",
       "  {'loss': 0.17236760258674622, 'step': 953},\n",
       "  {'loss': 0.2297724187374115, 'step': 954},\n",
       "  {'loss': 0.4948796033859253, 'step': 955},\n",
       "  {'loss': 0.8156436681747437, 'step': 956},\n",
       "  {'loss': 1.0016895532608032, 'step': 957},\n",
       "  {'loss': 0.1805894672870636, 'step': 958},\n",
       "  {'loss': 0.5150220394134521, 'step': 959},\n",
       "  {'loss': 0.3514273762702942, 'step': 960},\n",
       "  {'loss': 0.17486178874969482, 'step': 961},\n",
       "  {'loss': 0.23000486195087433, 'step': 962},\n",
       "  {'loss': 0.9214287996292114, 'step': 963},\n",
       "  {'loss': 0.39031827449798584, 'step': 964},\n",
       "  {'loss': 0.5774958729743958, 'step': 965},\n",
       "  {'loss': 0.5558385848999023, 'step': 966},\n",
       "  {'loss': 0.4422640800476074, 'step': 967},\n",
       "  {'loss': 0.6132107377052307, 'step': 968},\n",
       "  {'loss': 0.26854658126831055, 'step': 969},\n",
       "  {'loss': 0.5085665583610535, 'step': 970},\n",
       "  {'loss': 0.6053757071495056, 'step': 971},\n",
       "  {'loss': 0.27741292119026184, 'step': 972},\n",
       "  {'loss': 0.7945494055747986, 'step': 973},\n",
       "  {'loss': 0.5680866241455078, 'step': 974},\n",
       "  {'loss': 0.2832576334476471, 'step': 975},\n",
       "  {'loss': 0.8007960319519043, 'step': 976},\n",
       "  {'loss': 0.12370295822620392, 'step': 977},\n",
       "  {'loss': 1.1926034688949585, 'step': 978},\n",
       "  {'loss': 0.8473950624465942, 'step': 979},\n",
       "  {'loss': 0.4484577775001526, 'step': 980},\n",
       "  {'loss': 0.1985723376274109, 'step': 981},\n",
       "  {'loss': 0.19119805097579956, 'step': 982},\n",
       "  {'loss': 0.5959411859512329, 'step': 983},\n",
       "  {'loss': 0.40429264307022095, 'step': 984},\n",
       "  {'loss': 0.4302328824996948, 'step': 985},\n",
       "  {'loss': 0.14342257380485535, 'step': 986},\n",
       "  {'loss': 0.4165135622024536, 'step': 987},\n",
       "  {'loss': 0.4506634473800659, 'step': 988},\n",
       "  {'loss': 0.27324655652046204, 'step': 989},\n",
       "  {'loss': 0.3787882924079895, 'step': 990},\n",
       "  {'loss': 0.1626327484846115, 'step': 991},\n",
       "  {'loss': 0.6402730941772461, 'step': 992},\n",
       "  {'loss': 0.2840655744075775, 'step': 993},\n",
       "  {'loss': 0.544602632522583, 'step': 994},\n",
       "  {'loss': 0.6184592247009277, 'step': 995},\n",
       "  {'loss': 0.22519081830978394, 'step': 996},\n",
       "  {'loss': 0.1793016493320465, 'step': 997},\n",
       "  {'loss': 0.5758174657821655, 'step': 998},\n",
       "  {'loss': 0.22769784927368164, 'step': 999},\n",
       "  ...],\n",
       " 'val': [{'loss': np.float64(5.333535714582964), 'step': 0},\n",
       "  {'loss': np.float64(0.6255310256003348), 'step': 726},\n",
       "  {'loss': np.float64(0.4730518528622044), 'step': 1452},\n",
       "  {'loss': np.float64(0.44099426663611546), 'step': 2178},\n",
       "  {'loss': np.float64(0.42674432534816836), 'step': 2904},\n",
       "  {'loss': np.float64(0.4130977517501874), 'step': 3630},\n",
       "  {'loss': np.float64(0.40670870620110805), 'step': 4356},\n",
       "  {'loss': np.float64(0.41230175099220157), 'step': 5082},\n",
       "  {'loss': np.float64(0.4222626004922242), 'step': 5808},\n",
       "  {'loss': np.float64(0.39936808980077754), 'step': 6534},\n",
       "  {'loss': np.float64(0.4030796639190232), 'step': 7260},\n",
       "  {'loss': np.float64(0.42601092874018615), 'step': 7986},\n",
       "  {'loss': np.float64(0.38163327622758453), 'step': 8712},\n",
       "  {'loss': np.float64(0.44634500302928537), 'step': 9438},\n",
       "  {'loss': np.float64(0.39013009998670295), 'step': 10164},\n",
       "  {'loss': np.float64(0.37076332487843255), 'step': 10890},\n",
       "  {'loss': np.float64(0.3684976913096491), 'step': 11616},\n",
       "  {'loss': np.float64(0.3790569220138483), 'step': 12342},\n",
       "  {'loss': np.float64(0.3733462102957501), 'step': 13068},\n",
       "  {'loss': np.float64(0.3656478288683517), 'step': 13794},\n",
       "  {'loss': np.float64(0.3869467312700985), 'step': 14520},\n",
       "  {'loss': np.float64(0.377559835106627), 'step': 15246},\n",
       "  {'loss': np.float64(0.35984278399466485), 'step': 15972},\n",
       "  {'loss': np.float64(0.364094310832664), 'step': 16698},\n",
       "  {'loss': np.float64(0.35442919043962623), 'step': 17424},\n",
       "  {'loss': np.float64(0.3655733838061656), 'step': 18150},\n",
       "  {'loss': np.float64(0.35326429211711585), 'step': 18876},\n",
       "  {'loss': np.float64(0.4071077304345763), 'step': 19602},\n",
       "  {'loss': np.float64(0.3558984751974748), 'step': 20328},\n",
       "  {'loss': np.float64(0.34924340759180794), 'step': 21054},\n",
       "  {'loss': np.float64(0.3476599530001317), 'step': 21780},\n",
       "  {'loss': np.float64(0.35307635616295596), 'step': 22506},\n",
       "  {'loss': np.float64(0.3635595226891277), 'step': 23232},\n",
       "  {'loss': np.float64(0.3553480983149907), 'step': 23958},\n",
       "  {'loss': np.float64(0.34963399876863505), 'step': 24684},\n",
       "  {'loss': np.float64(0.3567737495326552), 'step': 25410},\n",
       "  {'loss': np.float64(0.3650967618835366), 'step': 26136},\n",
       "  {'loss': np.float64(0.35504763447179283), 'step': 26862},\n",
       "  {'loss': np.float64(0.3494474841974491), 'step': 27588},\n",
       "  {'loss': np.float64(0.35007675872607663), 'step': 28314},\n",
       "  {'loss': np.float64(0.34898862258092433), 'step': 29040}]}"
      ]
     },
     "execution_count": 18,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "execution_count": 18
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-02-25T14:18:47.823720Z",
     "start_time": "2025-02-25T14:18:47.721890Z"
    }
   },
   "source": [
    "#画线要注意的是损失是不一定在零到1之间的\n",
    "def plot_learning_curves(record_dict, sample_step=500):\n",
    "    # build DataFrame\n",
    "    train_df = pd.DataFrame(record_dict[\"train\"]).set_index(\"step\").iloc[::sample_step]\n",
    "    val_df = pd.DataFrame(record_dict[\"val\"]).set_index(\"step\")\n",
    "\n",
    "    # plot\n",
    "    for idx, item in enumerate(train_df.columns):\n",
    "        plt.plot(train_df.index, train_df[item], label=f\"train_{item}\")\n",
    "        plt.plot(val_df.index, val_df[item], label=f\"val_{item}\")\n",
    "        plt.grid()\n",
    "        plt.legend()\n",
    "        # plt.xticks(range(0, train_df.index[-1], 10*sample_step), range(0, train_df.index[-1], 10*sample_step))\n",
    "        plt.xlabel(\"step\")\n",
    "\n",
    "        plt.show()\n",
    "\n",
    "plot_learning_curves(record)  #横坐标是 steps"
   ],
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ],
      "image/png": "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"
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "execution_count": 19
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "## 测试集"
   ]
  },
  {
   "cell_type": "code",
   "metadata": {
    "ExecuteTime": {
     "end_time": "2025-02-25T14:19:15.311746Z",
     "start_time": "2025-02-25T14:19:15.079143Z"
    }
   },
   "source": [
    "model.eval()\n",
    "loss = evaluating(model, test_loader, loss_fct)\n",
    "print(f\"loss:     {loss:.4f}\")"
   ],
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "loss:     0.3575\n"
     ]
    }
   ],
   "execution_count": 20
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "pytorch",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.10.8"
  },
  "orig_nbformat": 4
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
